日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2024/1/23 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java图像处理之实现任意角度图像旋转 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原理及步驟:

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) << 24) | ((backgroundColor.getRed() & 0xff) << 16) | ((backgroundColor.getGreen() & 0xff) << 8)| ((backgroundColor.getBlue() & 0xff));resultImage.setRGB(i, j, rgb);}}}

5、完整的程序實現及測試

public class ImageRotate {/*** 創建任意角度的旋轉圖像* @param image* @param theta* @param backgroundColor* @return*/public BufferedImage rotateImage(BufferedImage image, double theta,Color backgroundColor) {int width = image.getWidth();int height = image.getHeight();double angle = theta * Math.PI / 180; // 度轉弧度double[] xCoords = getX(width / 2, height / 2, angle);double[] yCoords = getY(width / 2, height / 2, angle);int WIDTH = (int) (xCoords[3] - xCoords[0]);int HEIGHT = (int) (yCoords[3] - yCoords[0]);BufferedImage resultImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);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) << 24) | ((backgroundColor.getRed() & 0xff) << 16) | ((backgroundColor.getGreen() & 0xff) << 8)| ((backgroundColor.getBlue() & 0xff));resultImage.setRGB(i, j, rgb);}}}return resultImage;}// 獲取四個角點旋轉后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;}// 獲取四個角點旋轉后X方向坐標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;}public static void main(String[] args) throws Exception {File input = new File("C:/Users/admin/Desktop/1.jpg");File output = new File("C:/Users/admin/Desktop/2.png");BufferedImage image = ImageIO.read(input);Color bgColor = new Color(255, 255, 255);BufferedImage result = new ImageRotate().rotateImage(image, 45,bgColor);ImageIO.write(result, "png", output);} }

測試圖像:

旋轉45度后生成的png圖像:

?

?

總結

以上是生活随笔為你收集整理的java图像处理之实现任意角度图像旋转的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。