在 Java 中旋轉影象
本文將介紹我們如何使用兩種原生方式在 Java 中旋轉影象。
在 Java 中使用 BufferedImage
和 Graphics2D.rotate()
旋轉影象
第一種旋轉影象的方法包括使用 AWT 包附帶的 BufferedImage
和 Graphics2d
類。下面我們建立一個函式 rotateImage()
,它接收一個 BufferedImage
物件作為引數並返回一個旋轉的 BufferedImage
物件。
在 rotateImage()
中,我們使用 getWidth()
、getHeight()
和 getType()
方法獲取影象的寬度、高度和型別。現在我們呼叫 BufferedImage()
建構函式並將三個變數作為引數傳遞,它返回一個 BufferedImage
物件 newImageFromBuffer
。
我們使用 createGraphics()
方法建立新的旋轉影象,該方法返回一個 Graphics2D
物件 graphics2D
。使用這個物件,我們呼叫帶有三個引數的 rotate()
函式;第一個是旋轉影象的角度,因為我們想要將它旋轉 90 度,我們通過 Math.radians(90)
,第二個和第三個引數是 x 和 y 座標。
最後,我們呼叫 graphics2D.drawImage()
來繪製旋轉影象,它有四個引數,即 BufferedImage
物件、要應用的過濾器以及 x 和 y 座標。然後我們返回 newImageFromBuffer
物件。
在 main
函式中,我們使用 File
讀取檔案,然後使用 ImageIO.read()
將其轉換為 BufferedImage
物件。現在我們呼叫 rotateImage()
函式並傳遞返回的 BufferedImage
物件並儲存旋轉後的 BufferedImage
物件。現在我們有了旋轉的影象,我們需要使用 File
和 ImageIO.write()
建立一個新檔案來儲存它,該檔案採用 BufferedImage
物件,其副檔名是空檔案的位置。
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class RotateImage {
public static BufferedImage rotateImage(BufferedImage imageToRotate) {
int widthOfImage = imageToRotate.getWidth();
int heightOfImage = imageToRotate.getHeight();
int typeOfImage = imageToRotate.getType();
BufferedImage newImageFromBuffer = new BufferedImage(widthOfImage, heightOfImage, typeOfImage);
Graphics2D graphics2D = newImageFromBuffer.createGraphics();
graphics2D.rotate(Math.toRadians(90), widthOfImage / 2, heightOfImage / 2);
graphics2D.drawImage(imageToRotate, null, 0, 0);
return newImageFromBuffer;
}
public static void main(String[] args) {
try {
BufferedImage originalImage = ImageIO.read(new File("mountains.jpeg"));
BufferedImage subImage = rotateImage(originalImage);
File rotatedImageFile = new File("C:\\Users\\User1\\Documents\\mountainsRotated.jpeg");
ImageIO.write(subImage, "jpg", rotatedImageFile);
System.out.println("New Rotated Image File Path: " + rotatedImageFile.getPath());
} catch (IOException e) {
e.printStackTrace();
}
}
}
輸出:
New Rotated Image File Path: C:\Users\User1\Documents\mountainsRotated.jpeg
原圖:
旋轉影象:
在 Java 中使用仿射變換旋轉影象
此示例使用 AffineTransform
類,該類將影象從其原始 2D 座標線性對映到其他 2D 座標,而不會損失原始質量。在下面的程式中,我們三個方法,一是讀取和呼叫其他函式,二是順時針旋轉影象,最後一個函式是逆時針旋轉影象。
在 rotateImage()
函式中,我們使用 new File()
讀取影象,並使用 ImageIO.read()
將其轉換為 BufferedImage
物件。然後我們建立另一個 BufferedImage
物件,該物件保留原始影象的屬性並將其稱為 output
。接下來,我們呼叫 rotateImageClockWise()
方法並在其中傳遞原始 BufferedImage
,該方法返回 AffineTransorm
類的物件。
rotateImageClockWise()
接收 image
並獲取高度和寬度。我們建立一個 AffineTransform
物件 affineTransform
並使用它呼叫 rotate()
方法。在 rotate()
中,我們傳遞三個引數;第一個是以弧度為單位的旋轉角度,這裡我們傳遞 Math.PI / 2
,最後兩個引數是 x 和 y 座標,它們是影象寬度和高度的一半。
現在,隨著影象的旋轉,我們使用 translate()
函式在新座標中平移影象,該函式採用兩個引數:x 方向旋轉的距離和 y 方向旋轉的距離。我們使用 (imageWidth - imageHeight) / 2
計算 x 和 y 引數。
要逆時針旋轉影象,我們可以在 rotate()
中呼叫方法 rotateImageCounterClockwise()
而不是 rotateImageClockWise()
。
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class RotateImage {
private static final String INPUT_FILE_NAME = "mountains.jpeg";
private static final String OUTPUT_FILE_NAME = "mountainsRotated.jpeg";
private AffineTransform rotateImageClockWise(BufferedImage image) {
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
AffineTransform affineTransform = new AffineTransform();
affineTransform.rotate(Math.PI / 2, imageWidth / 2, imageHeight / 2);
double offset = (imageWidth - imageHeight) / 2;
affineTransform.translate(offset, offset);
return affineTransform;
}
private AffineTransform rotateImageCounterClockwise(BufferedImage image) {
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
AffineTransform affineTransform = new AffineTransform();
affineTransform.rotate(-Math.PI / 2, imageWidth / 2, imageHeight / 2);
double offset = (imageWidth - imageHeight) / 2;
affineTransform.translate(-offset, -offset);
return affineTransform;
}
private void rotateImage() throws Exception {
BufferedImage bufferedImage = ImageIO.read(new File(INPUT_FILE_NAME));
BufferedImage output = new BufferedImage(
bufferedImage.getHeight(), bufferedImage.getWidth(), bufferedImage.getType());
AffineTransform affineTransform = rotateImageClockWise(bufferedImage);
AffineTransformOp affineTransformOp =
new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_BILINEAR);
affineTransformOp.filter(bufferedImage, output);
ImageIO.write(output, "jpg", new File(OUTPUT_FILE_NAME));
}
public static void main(String[] args) {
try {
RotateImage rotateImage = new RotateImage();
rotateImage.rotateImage();
} catch (Exception e) {
e.printStackTrace();
}
}
}
輸出:
原圖:
影象順時針旋轉:
影象逆時針旋轉:
Rupam Saini is an android developer, who also works sometimes as a web developer., He likes to read books and write about various things.
LinkedIn