如何创建90度旋转缓冲图像的反转?

时间:2017-11-06 17:43:12

标签: java image bufferedimage

我不能为我的生活弄清楚这个功能如何起作用,更不用说如何创建一个撤消。我试图编辑这个图像编辑程序,我需要为这个rotate90过滤器添加一个撤消功能。要清楚,我知道之前已经问过类似的问题,我已经看到了大约20个相关的stackoverflow问题,但我只是不理解它。

public static void apply(ColorImage image) {
    int height = image.getHeight();
    int width = image.getWidth();


    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            Color pix = image.getPixel(x, y);
            image.setPixel(height - y - 1, x, pix);
        }
    }
}

上面的代码假设顺时针旋转了90度的缓冲图像。我该如何创建此函数的反函数?

1 个答案:

答案 0 :(得分:2)

要了解旋转功能应如何工作,请考虑字母F的图像,宽3像素,高5像素,旋转90度:

\  0 1 2        \  0 1 2 3 4
 +------         +----------
0| * * *        0| * * * * *
1| *            1|     *   *
2| * *          2|         *
3| *
4| *

您可以看到( 0 ,0)处的*像素应映射到旋转图像中(4, 0 )处的像素; ( 1 ,0)处的像素映射到(4, 1 )处的像素; ( 2 ,0)到(4, 2 ),...(等等)的像素......最后,( 0 ,4)映射到(0, 0

应该立即明显的是,第一个坐标(原始图像的x)映射到旋转图像的y坐标。 (我已将这些数字加在上面)。这可以解释为什么x值在y调用中显示为setPixel()坐标:

image.setPixel(???, x, pix);

将原始图像的y坐标转换为旋转图像的x坐标并不复杂得多。第0行成为最后一列,最后一行成为第0列。由于原始图像高5像素,因此旋转的图像变为5像素宽,最后一列为height-1。当y向下增加原始图像时,旋转图像的相应列会减少,为旋转的height-1-y列提供x

image.setPixel(height - y - 1, x, pix);

两个问题:

1)利用这个3像素×5像素的图像,(0,0)处的像素映射到(4,0),这超出了image的范围;在该坐标处设置像素的颜色应该为您提供IndexOutOfBoundsException

2)如果图像是方形的(从而避免了IndexOutOfBoundsException异常),则在读取原始像素值之前,您将用翻译的像素值覆盖原始图像的一些像素值。这会破坏你的形象。

上述两个问题都有一个简单的解决方法。创建并返回一个新图像。

扭转轮换

如果原始旋转将像素移动到(0,0)到(4,0),要反转旋转,则需要将像素移动到(4,0)到(0,0)。这可以通过两种方式完成:

  1. 稍微调整坐标的变换,或
  2. 从翻译的像素坐标读取并写入非翻译的像素坐标。
  3. 留给学生锻炼。