繁体   English   中英

图片旋转码有什么问题?

[英]What's wrong with image rotation code?

图像以下面的代码旋转,但是错误,原始图像上出现了一些黑点。 我相信这与轮换代码有关。 有什么办法吗? 谢谢。 图像尺寸为32x32像素,加载在屏幕中央(320x240)。

public class RendPanel extends JPanel {

    private static final long serialVersionUID = 1L;

    int widthe  = 320;
    int heighte = 240;

    double angle = Math.toRadians(220);
    double sin = Math.sin(angle);
    double cos = Math.cos(angle);
    double x0 = 0.5 * (widthe  - 1);     // point to rotate about
    double y0 = 0.5 * (heighte - 1);     // center of image

    public static BufferedImage fbuffer;
    public RendPanel(int width, int height) {
        fbuffer = new BufferedImage(320, 240, BufferedImage.TYPE_INT_RGB);

        BufferedImage in = null;
        try { in = ImageIO.read(new File("square.png")); } //32x32 square .png
        catch (IOException e) { e.printStackTrace(); }

        for (int i = 0; i < in.getWidth(); i++) {
            for (int j = 0; j < in.getHeight(); j++) {
                fbuffer.setRGB(i + (320 / 2) - 16, j + (240 / 2) - 16, in.getRGB(i, j));
            }
        }

        BufferedImage neww = new BufferedImage(320, 240, BufferedImage.TYPE_INT_RGB);

        for (int x = 0; x < widthe; x++) {
            for (int y = 0; y < heighte; y++) {
                if(x >= x0 - 32 && x <= x0 + 32 && y >= y0 - 32 && y <= y0 + 32){
                    double a = x - x0;
                    double b = y - y0;
                    int xx = (int) (+a * cos - b * sin + x0);
                    int yy = (int) (+a * sin + b * cos + y0);

                    // plot pixel (x, y) the same color as (xx, yy) if it's in bounds
                    if (xx >= 0 && xx < width && yy >= 0 && yy < height) {
                        neww.setRGB(xx, yy, fbuffer.getRGB(x, y));
                    }
                }
            }
        }

        fbuffer = neww;
        repaint();

        setPreferredSize(new Dimension(width, height));
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.drawImage(fbuffer, 0, 0, null);
    }
}

初学者的错误(对不起)。

依次获取每个源像素,将坐标转换到目标并复制像素值是不正确的方法,因为常规输入网格将不会映射到常规网格,并且会存在空隙(并重叠)。

正确的方法是扫描目标图像(以便到达每个目标像素)并反变换坐标以从源获取像素值。

作为改进,可以使用从源中着陆的位置开始执行的四个相邻像素并执行双线性插值,以减少混叠。

伙计,这很奇怪,因为在此代码中它可以正常工作!

这是一个工作代码:

public class RendPanel extends JPanel {

    private static final long serialVersionUID = 1L;

    int widthe  = 320;
    int heighte = 240;

    int ang = 0;
    double x0 = 0.5 * (widthe  - 1);     // point to rotate about
    double y0 = 0.5 * (heighte - 1);     // center of image

    public static BufferedImage fbuffer;
    public RendPanel(int width, int height) {
        fbuffer = new BufferedImage(320, 240, BufferedImage.TYPE_INT_RGB);

        BufferedImage in = null;
        try { in = ImageIO.read(new File("square.png")); } //32x32 square .png
        catch (IOException e) { e.printStackTrace(); }

        for (int i = 0; i < in.getWidth(); i++) {
            for (int j = 0; j < in.getHeight(); j++) {
                fbuffer.setRGB(i + (320 / 2) - 16, j + (240 / 2) - 16, in.getRGB(i, j));
            }
        }

        setPreferredSize(new Dimension(width, height));
    }

    BufferedImage neww;
    public void r(){
        neww = new BufferedImage(320, 240, BufferedImage.TYPE_INT_RGB);

        double angle = Math.toRadians(ang);
        double sin = Math.sin(angle);
        double cos = Math.cos(angle);

        for (int x = 0; x < widthe; x++) {
            for (int y = 0; y < heighte; y++) {
                if(x >= x0 - 32 && x <= x0 + 32 && y >= y0 - 32 && y <= y0 + 32){
                    double a = x - x0;
                    double b = y - y0;
                    int xx = (int) (+a * cos - b * sin + x0);
                    int yy = (int) (+a * sin + b * cos + y0);

                    // plot pixel (x, y) the same color as (xx, yy) if it's in bounds
                    if (xx >= 0 && xx < widthe && yy >= 0 && yy < heighte) {
                        neww.setRGB(x, y, fbuffer.getRGB(xx, yy));
                    }
                }
            }
        }

        ang++;
        repaint();
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.drawImage(neww, 0, 0, null);
    }
}

感谢您: https : //introcs.cs.princeton.edu/java/31datatype/Rotation.java.html

编辑:您必须反转bf2.setRGB(x, y, fbuffer.getRGB(xx, yy));上的vars bf2.setRGB(x, y, fbuffer.getRGB(xx, yy)); 到旋转的坐标。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM