Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this code only rotate squares?

I will use this algorithm for image rotation, however I realized that it only rotates squares, not rectangles.

Would anyone know why?

Main code-problem:

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 alter to 33 width or height the result will be wrong (wrong image).

like image 465
Jlmi Xczffav Avatar asked Apr 17 '26 23:04

Jlmi Xczffav


1 Answers

You algorithm actually does work. The problem is with your loops in your context application. Because the pixels are stored in raster order, the outer loop needs to iterate to the height and the inner loop iterates to the width, e.g:

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 height to 40 for example:

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

The loops need to change like this:

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 the loops (height then width) compared to the function call (width then height).

like image 162
samgak Avatar answered Apr 19 '26 13:04

samgak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!