java图像处理之实现任意角度图像旋转

您所在的位置:网站首页 圆形旋转图案的原理 java图像处理之实现任意角度图像旋转

java图像处理之实现任意角度图像旋转

2023-10-21 22:12| 来源: 网络整理| 查看: 265

原理及步骤:

1、旋转角度:图像顺时针或逆时针旋转的角度,以θ表示,需要用户输入;

2、旋转中心:一般以图像中心作为旋转中心,周围像素围绕其旋转;

3、画布大小:由于图像旋转后产生的图像宽和高与原始图像不同,需要先计算好旋转后的画布大小。由于一般处理的图像都是矩形阵列,不考虑特殊形状前提下,我们只需要计算原始图像四个角点坐标围绕中心旋转θ角度后的坐标,取X方向最大最小值之差作为画布宽,Y方向最大最小值之差作为画布高,以此生成一幅空图像;

4、像素赋值:得到画布图像之后,将画布坐标系与原始图像坐标系进行统一,即画布中心与原始图像中心都改正为(0,0)位置,将画布上每个像素进行θ角的反方向旋转,即旋转回原始图像位置,如果旋转后的像素落在原始图像坐标范围内,取该位置最近像素RGB值作为画布上对应像素RGB值;

5、空像素处理:由于旋转后,画布上可能有部分区域在原图没有对应范围,这部分像素为空像素,也可以叫做背景像素,这部分像素可以通过自定义背景色进行赋值。如果输出图片格式为jpg,由于Windows图片浏览工具背景色为白色,建议将背景色输出为白色;

6、背景色透明:如果需要将画布中空像素设置为透明,需要在初始化画布时将画布类型设置为TYPE_INT_ARGB,即png图像对应的格式,输出时也输出为png格式图像即可。

图像旋转java实现:

1、由于java中math三角函数都是以弧度进行计算的,需要将角度转换为弧度。

                                              double angle = theta * Math.PI / 180;

2、计算按照逆时针旋转θ角度后画布大小,即X和Y方向旋转后最大最小值。因为旋转为图像中心,由于中心对称,只需要计算对角线上其中一个坐标,对角线另一个取负即可,之后对四个值进行排序并返回排序后数组。取第一和第二象限两个角点进行计算,先计算原图第一象限角点相对坐标系弧度,第二象限相对坐标系弧度=π-第一象限弧度。

获取X方向旋转后坐标数组:先计算第一象限角点相对中心距离radius,计算该角点弧度angle1,通过反余弦计算得到,再通过计算原图本身弧度加上旋弧度angle后的余弦。

private double[] getX(int i, int j, double angle) { double results[] = new double[4]; double radius = Math.sqrt(i * i + j * j); double angle1 = Math.acos(i / radius); results[0] = radius * Math.cos(angle1 + angle); results[1] = radius * Math.cos(Math.PI - angle1 + angle); results[2] = -results[0]; results[3] = -results[1]; Arrays.sort(results); return results; }

获取Y方向旋转后坐标数组:

private double[] getY(int i, int j, double angle) { double results[] = new double[4]; double radius = Math.sqrt(i * i + j * j); double angle1 = Math.asin(j / radius); results[0] = radius * Math.sin(angle1 + angle); results[1] = radius * Math.sin(Math.PI - angle1 + angle); results[2] = -results[0]; results[3] = -results[1]; Arrays.sort(results); return results; }

3、根据X和Y方向最大最小值作为宽和高生成画布,画布类型根据需要进行设置,需要输出影像背景透明的png图像,类型设置为BufferedImage.TYPE_INT_ARGB,如果原始图像为png格式,也可以直接使用image.getType(),用原始图像格式进行赋值。

int WIDTH = (int) (xCoords[3] - xCoords[0]); int HEIGHT = (int) (yCoords[3] - yCoords[0]); BufferedImage resultImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);

4、对画布每一个像素位置进行逐一计算,计算每个位置按照顺时针旋转θ角后位置,判断该位置是否在原图范围内,在原图范围内,则直接取原图上该位置rgb值对画布对应像素进行赋值,原图范围以外的,通过预先传入的背景色参数进行赋值。由于画布上像素相对坐标系弧度是通过反余弦函数计算的,反余弦取值为(0,π),对于第三四象限的像素,通过判断y坐标是否大于0,大于0则直接计算,小于0,说明该像素位于三四象限,通过计算2π减去反余弦后弧度得到该像素相对坐标系弧度。

for (int i = 0; i < WIDTH; i++) { for (int j = 0; j < HEIGHT; j++) { int x = i - WIDTH / 2; int y = HEIGHT / 2 - j; double radius = Math.sqrt(x * x + y * y); double angle1; if (y > 0) { angle1 = Math.acos(x / radius); } else { angle1 = 2 * Math.PI - Math.acos(x / radius); } x = (int) (radius * Math.cos(angle1 - angle)); y = (int) (radius * Math.sin(angle1 - angle)); if (x < (width / 2) & x > -(width / 2) & y < (height / 2) & y > -(height / 2)) { int rgb = image.getRGB(x + width / 2, height / 2 - y); resultImage.setRGB(i, j, rgb); }else { int rgb = ((0 & 0xff) -(height / 2)) { int rgb = image.getRGB(x + width / 2, height / 2 - y); resultImage.setRGB(i, j, rgb); }else { int rgb = ((0 & 0xff)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3