我一开始都无法弄清楚这个函数是如何工作的,更不用说如何创建撤消了。我正在尝试编辑这个图像编辑程序,并且我需要为这个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 度。我如何创建这个函数的反函数?
最佳答案
要了解旋转函数的工作原理,请考虑字母 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) 处的像素strong>,4) 映射到 (0,0)
很明显,第一个坐标(原始图像的 x 坐标)映射到旋转图像的 y 坐标。 (我在上面将这些值加粗了)。这应该可以解释为什么 x
值在 setPixel()
调用中显示为 y
坐标:
image.setPixel(???, x, pix);
将原始图像的 y
坐标转换为旋转图像的 x
坐标并不复杂。第 0 行成为最后一列,最后一行成为第 0 列。由于原始图像为 5 像素高,旋转后的图像变为 5 像素宽,最后一列为 height-1
。随着 y
沿着原始图像向下增加,旋转图像的相应列会减小,从而为旋转的 x
列提供 height-1-y
。
image.setPixel(height - y - 1, x, pix);
<小时/>
两个问题:
1) 对于这个 3 像素 x 5 像素的图像,(0,0) 处的像素映射到 (4,0),这超出了 image
的范围;设置该坐标处像素的颜色应该会给您一个 IndexOutOfBoundsException
。
2) 如果图像是方形的(从而避免 IndexOutOfBoundsException
异常),则在读取原始像素值之前,您将用转换后的像素值覆盖原始图像的某些像素值。这会破坏你的形象。
有一个简单的方法可以解决上述两个问题。创建并返回一个新图像。
<小时/>反转旋转
如果原始旋转将 (0,0) 处的像素移动到 (4,0),要反转旋转,您需要将 (4,0) 处的像素移动到 (0,0)。这可以通过两种方式来完成:
- 稍微调整坐标的变换,或者
- 读取已转换的像素坐标并写入未转换的像素坐标。
练习留给学生。
关于java - 如何创建将缓冲图像旋转 90 度的反转?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47142757/