Why does this code only rotate the squares?

I will use this algorithm to rotate the image, however I realized that it only rotates squares, not rectangles.

Does anyone know why?

Main problem code:

public static int[] rotate(double angle, int[] pixels, int width, int height) {
    final double radians = Math.toRadians(angle);

    final double cos = Math.cos(radians);
    final double sin = Math.sin(radians);

    final int[] pixels2 = new int[pixels.length];

    for(int pixel = 0; pixel < pixels2.length; pixel++) {
        pixels2[pixel] = 0xFFFFFF;
    }

    for(int x = 0; x < width; x++) {
        for(int y = 0; y < height; y++) {
            final int centerx = width / 2;
            final int centery = height / 2;
            final int m = x - centerx;
            final int n = y - centery;
            final int j = ((int) ( m * cos + n * sin ) ) + centerx;
            final int k = ((int) ( n * cos - m * sin ) ) + centery;
            if( j >= 0 && j < width && k >= 0 && k < height ){
                pixels2[ ( y * width + x ) ] = pixels[ ( k * width + j ) ];
            }
        }
    }
    return pixels2;
}

      

Context application:

try {
    BufferedImage testrot = ImageIO.read(new File("./32x32.png"));

    int[] linearpixels = new int[testrot.getWidth() * testrot.getHeight()];
    int c = 0;
    for(int i = 0; i < testrot.getWidth(); i++){
        for(int j = 0; j < testrot.getHeight(); j++){
            linearpixels[c] = testrot.getRGB(i, j);
            c++;
        }
    }

    int[] lintestrot = rotate(50, linearpixels, 32, 32);
    BufferedImage image = new BufferedImage(70, 70, BufferedImage.TYPE_INT_RGB);
    c = 0;
    for(int i = 0; i < 32; i++){
        for(int j = 0; j < 32; j++){
            image.setRGB(i, j, lintestrot[c]);
            c++;
        }
    }

    File outputfile = new File("test002.bmp");
    ImageIO.write(image, "bmp", outputfile);

} catch (IOException e1) {
    e1.printStackTrace();
}

      

If you change to 33 widths or heights, the result is wrong (wrong image).

+3


source to share


1 answer


In fact, the algorithm works. The problem is with your loops in your context app. Since pixels are stored in bitmap order, the outer loop needs to iterate to the height, and the inner loop repeats to the width, for example:

for(int i = 0; i < testrot.getHeight(); i++){
    for(int j = 0; j < testrot.getWidth(); j++){
        linearpixels[c] = testrot.getRGB(j, i); //edit here, tested
        c++;
    }
}

      

Then if you change the height to 40, for example:

int[] lintestrot = rotate(50, linearpixels, 32, 40);

      



The cycles should change as follows:

c = 0;
for(int i = 0; i < 40; i++){
    for(int j = 0; j < 32; j++){
        image.setRGB(i, j, lintestrot[c]);
        c++;
    }
}

      

Note that the order is reversed in a loop (height, then width) versus the function call (width, then height).

+2


source







All Articles