Java中縮放緩衝影像

banq發表於2024-04-13

在本教程中,我們將介紹如何使用基本 Java API 重新縮放影像。我們將展示如何從檔案載入影像和將影像儲存到檔案,並解釋重新縮放過程的一些技術方面。

1、用Java載入影像
在本教程中,我們將使用一個簡單的 JPG 影像檔案。我們將使用與基本 Java SDK 捆綁在一起的ImageIO API 載入它。該 API 有一些預設的ImageReader,適用於 JPEG 和 PNG 等格式。ImageReaders知道如何讀取各自的影像格式並從影像檔案中獲取點陣圖。

我們將使用的方法是 來自 ImageIO 的讀取方法。此方法有一些過載,但我們將使用最簡單的一個:

BufferedImage srcImg = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));

正如我們所看到的,read()方法提供了一個BufferedImage物件,它是影像點陣圖的主要 Java 表示形式。

2.、重新縮放影像
在重新縮放載入的影像之前,我們必須做一些準備工作。

建立目標影像
首先,我們必須建立一個新的 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的顏色空間。該類本身為受支援的值提供靜態 int成員,例如 分別針對彩色和灰度影像的BufferedImage.TYPE_INT_RGB和BufferedImage.TYPE_BYTE_GRAY 。在我們的例子中,我們將使用與源影像相同的型別,因為我們只是更改比例。

下一步是應用轉換,將源影像調整為我們的目標大小。

應用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"));

 

相關文章