如何在 Java 中縮放緩衝影像?
一、簡介
在本教程中,我們將介紹如何使用基本 Java API 重新縮放圖像。我們將展示如何從文件加載圖像並將圖像保存到文件,並解釋重新縮放過程的一些技術方面。
2. 用Java載入圖像
在本教程中,我們將使用一個簡單的 JPG 圖像檔案。我們將使用與基本 Java SDK 捆綁在一起的ImageIO
API 來載入它。該 API 有一些預設的ImageReaders
適用於 JPEG 和 PNG 等格式。 ImageReaders
知道如何讀取各自的圖像格式並從圖像檔案中獲取點陣圖。
我們將使用的方法是來自ImageIO
read
方法。此方法有一些重載,但我們將使用最簡單的一個:
BufferedImage srcImg = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
正如我們所看到的, read()
方法提供了一個BufferedImage
對象,它是圖像點陣圖的主要 Java 表示形式。
3. 重新縮放影像
在重新縮放載入的圖像之前,我們必須做一些準備。
3.1.建立目標影像
首先,我們必須建立一個新的BufferedImage
對象,表示記憶體中縮放後的圖像,也稱為目標圖像。由於我們要重新縮放,這意味著生成的圖像將具有與原始圖像不同的寬度和高度。
我們必須在新的BufferedImage:
float scaleW = 2.0f, scaleH = 2.0f;
int w = srcImg.getWidth() * (int) scaleW;
int h = srcImg.getHeight() * (int) scaleH;
BufferedImage dstImg = new BufferedImage(w, h, srcImg.getType());
如程式碼所示,寬度和高度的縮放因子不需要相同。然而,它們通常是這樣的,因為使用不同的縮放因子會為我們帶來扭曲的結果。
BufferedImage
建構子還需要一個imageType
參數。不要將其與圖片檔案格式(例如 PNG 或 JPEG)混淆;圖像類型決定了新BufferedImage
的色彩空間。該類別本身為受支援的值提供static int
成員,例如分別針對彩色和灰階影像的BufferedImage.TYPE_INT_RGB
和BufferedImage.TYPE_BYTE_GRAY
。在我們的例子中,我們將使用與來源圖像相同的類型,因為我們只是更改比例。
下一步是應用轉換,將來源圖像調整為我們的目標大小。
3.2.應用AffineTransform
我們將透過應用縮放仿射變換來縮放影像。這些線性變換可以將點從一個 2D 平面映射到另一個 2D 平面。根據變換,目標平面可以是原始平面的放大甚至旋轉版本。
在我們的例子中,我們將僅套用縮放。最簡單的思考方法是獲取構成圖像的所有點,並透過縮放因子 來增加它們之間的距離。
讓我們建立一個AffineTransform
及其各自的操作:
AffineTransform scalingTransform = new AffineTransform();
scalingTransform.scale(scaleW, scaleH);
AffineTransformOp scaleOp = new AffineTransformOp(scalingTransform, AffineTransformOp.TYPE_BILINEAR);
AffineTransform
定義我們將要套用什麼操作,而AffineTransformOp
定義它的應用方式。我們建立一個使用scalingTransform
的操作,並使用雙線性插值來應用它。
所選的插值演算法是根據具體情況確定的,並指示如何選擇新影像的像素值。這些插值演算法的作用以及為什麼它們是強制性的超出了本文的範圍。理解它們需要知道我們為什麼使用這些線性變換以及它們如何應用於 2D 影像。
一旦scaleOp
準備好,我們就可以將其應用到srcImg
並將結果放入dstImg
:
dstImg = scaleOp.filter(srcImg, dstImg);
最後,我們可以將dstImg
保存到文件中,以便我們可以查看結果:
ImageIO.write(dstImg, "jpg", new File("src/main/resources/images/resized.jpg"));
4。結論
在本文中,我們學習如何以任意比例因子縮放影像。我們展示瞭如何從檔案系統載入/儲存映像以及如何使用 Java 的AffineTransform
來應用縮放操作。
與往常一樣,本文的源代碼可用 在 GitHub 上。與往常一樣,本文的源代碼可用 在 GitHub 上。