在 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