1. 序章

このチュートリアルでは、Javaを使用して画像のサイズを変更(拡大縮小)する方法を学習します。 画像のサイズ変更機能を提供するコアJavaとオープンソースのサードパーティライブラリの両方について説明します。

画像を拡大および縮小の両方で拡大縮小できることに言及することが重要です。 このチュートリアルのコードサンプルでは、実際にはこれが最も一般的なシナリオであるため、画像のサイズを小さいサイズに変更します。

2. CoreJavaを使用して画像のサイズを変更する

Core Javaは、画像のサイズを変更するために次のオプションを提供します。

2.1. java .awt.Graphics2D

Graphics2D は、Javaプラットフォームで2次元の形状、テキスト、および画像をレンダリングするための基本的なクラスです。

Graphics2Dを使用して画像のサイズを変更することから始めましょう。

BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws IOException {
    BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
    Graphics2D graphics2D = resizedImage.createGraphics();
    graphics2D.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);
    graphics2D.dispose();
    return resizedImage;
}

サイズ変更の前後の画像がどのように見えるかを見てみましょう。

   

BufferedImage.TYPE_INT_RGB パラメーターは、画像のカラーモデルを示します。 使用可能な値の完全なリストは、公式のJavaBufferedImageドキュメントにあります。

Graphics2D は、RenderingHintsと呼ばれる追加のパラメーターを受け入れます。 RenderingHintsを使用して、さまざまな画像処理の側面に影響を与え、最も重要なのは画像の品質と処理時間に影響を与えることです。

setRenderingHint メソッドを使用して、RenderingHintを追加できます。

graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

RenderingHints の完全なリストは、このOracleチュートリアルにあります。

2.2. Image.getScaledInstance()

画像を使用するこのアプローチは非常に単純で、満足のいく品質の画像を生成します。

BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws IOException {
    Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_DEFAULT);
    BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
    outputImage.getGraphics().drawImage(resultingImage, 0, 0, null);
    return outputImage;
}

おいしいものの写真で何が起こるか見てみましょう:

   

getScaledInstance()メソッドに、画像のリサンプリングのニーズに使用するアルゴリズムのタイプを示すフラグを提供することで、利用可能なアプローチの1つを使用するようにスケーリングメカニズムを指示することもできます。

Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_SMOOTH);

使用可能なすべてのフラグは、公式のJavaイメージドキュメントで説明されています。

3. Imgscalr

Imgscalr は、バックグラウンドでGraphic2Dを使用します。 画像のサイズを変更するためのいくつかの異なるメソッドを備えたシンプルなAPIがあります。

Imgscalrは、選択したスケーリングオプションに応じて、見栄えの良い結果、最速の結果、またはバランスの取れた結果のいずれかを提供します。トリミングや回転など、他の画像操作機能も利用できます。 簡単な例でそれがどのように機能するかを示しましょう。

次のMaven依存関係を追加します。

<dependency>
    <groupId>org.imgscalr</groupId>
    <artifactId>imgscalr-lib</artifactId>
    <version>4.2</version>
</dependency>

最新バージョンについては、 MavenCentralを確認してください。

Imgscalrを使用する最も簡単な方法は次のとおりです。

BufferedImage simpleResizeImage(BufferedImage originalImage, int targetWidth) throws Exception {
    return Scalr.resize(originalImage, targetWidth);
}

ここで、 originalImageはサイズ変更するBufferedImage であり、targetWidthは結果画像の幅です。 このアプローチでは、元の画像の比率が維持され、デフォルトのパラメーターMethod.AUTOMATICおよびMode.AUTOMATICが使用されます。

おいしい果物の写真はどうですか? どれどれ:

   

このライブラリでは、複数の構成オプションも使用でき、背景の画像の透明度を処理します。

最も重要なパラメータは次のとおりです。

  • mode –アルゴリズムが使用するサイズ変更モードを定義するために使用されます。 たとえば、画像の比率を維持するかどうかを定義できます(オプションは、 AUTOMATIC、FIT_EXACT、FIT_TO_HEIGHT、およびFIT_TO_WIDTH )です。
  • method –速度、品質、またはその両方に焦点が当てられるように、サイズ変更プロセスを指示します。 可能な値は、 AUTOMATIC、BALANCED、QUALITY、SPEED、ULTRA_QUALITYです。

追加のサイズ変更プロパティを定義して、ログを記録したり、ライブラリに画像の色を変更するように指示したりすることもできます(画像を明るく、暗く、グレースケールにするなど)。

full resize()メソッドのパラメーター化を使用してみましょう。

BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws Exception {
    return Scalr.resize(originalImage, Scalr.Method.AUTOMATIC, Scalr.Mode.AUTOMATIC, targetWidth, targetHeight, Scalr.OP_ANTIALIAS);
}

そして今、私たちは得ます:

   

Imgscalrは、Java Image IOでサポートされているすべてのファイル(JPG、BMP、JPEG、WBMP、PNG、およびGIF)で動作します。

4. サムナイレーター

Thumbnailator は、プログレッシブバイリニアスケーリングを使用するJava用のオープンソースの画像サイズ変更ライブラリです。 JPG、BMP、JPEG、WBMP、PNG、およびGIFをサポートします。

次のMaven依存関係をpom.xmlに追加して、プロジェクトに含めます。

<dependency>
    <groupId>net.coobird</groupId>
    <artifactId>thumbnailator</artifactId>
    <version>0.4.11</version>
</dependency>

利用可能な依存関係のバージョンは、 MavenCentralにあります。

非常にシンプルなAPIを備えており、出力品質をパーセンテージで設定できます。

BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws Exception {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    Thumbnails.of(originalImage)
        .size(targetWidth, targetHeight)
        .outputFormat("JPEG")
        .outputQuality(1)
        .toOutputStream(outputStream);
    byte[] data = outputStream.toByteArray();
    ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
    return ImageIO.read(inputStream);
}

サイズ変更の前後で、この笑顔の写真がどのように見えるかを見てみましょう。

   

バッチ処理のオプションもあります。

Thumbnails.of(new File("path/to/directory").listFiles())
    .size(300, 300)
    .outputFormat("JPEG")
    .outputQuality(0.80)
    .toFiles(Rename.PREFIX_DOT_THUMBNAIL);

Imgscalrとして、Thumblinatorは、Java Image IOでサポートされているすべてのファイル(JPG、BMP、JPEG、WBMP、PNG、およびGIF)で動作します。

5. マーヴィン

Marvin は、画像操作に便利なツールであり、多くの便利な基本(トリミング、回転、傾斜、反転、拡大縮小)および高度な(ぼかし、エンボス、テクスチャリング)機能を提供します。

前と同じように、Marvinのサイズ変更に必要なMavenの依存関係を追加します。

<dependency>
    <groupId>com.github.downgoon</groupId>
    <artifactId>marvin</artifactId>
    <version>1.5.5</version>
    <type>pom</type>
</dependency>
<dependency>
    <groupId>com.github.downgoon</groupId>
    <artifactId>MarvinPlugins</artifactId>
    <version>1.5.5</version>
</dependency>

利用可能なMarvin依存関係バージョンは、 Marvinプラグインバージョンとともに、 MavenCentralにあります。

Marvinの欠点は、追加のスケーリング構成を提供しないことです。 また、スケール方法では、画像と画像のクローンが必要ですが、これは少し面倒です。

BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
    MarvinImage image = new MarvinImage(originalImage);
    Scale scale = new Scale();
    scale.load();
    scale.setAttribute("newWidth", targetWidth);
    scale.setAttribute("newHeight", targetHeight);
    scale.process(image.clone(), image, null, null, false);
    return image.getBufferedImageNoAlpha();
}

花の画像のサイズを変更して、どのように表示されるかを見てみましょう。

   

6. ベストプラクティス

画像処理はリソースの面でコストのかかる操作であるため、本当に必要でない場合は、最高品質を選択することが必ずしも最良の選択肢とは限りません。

すべてのアプローチのパフォーマンスを見てみましょう。 私たちは1つ取った 1920×1920ピクセル画像、およびそれをに拡大縮小 200×200ピクセル。 結果として観測された時間は次のとおりです。

  • java.awt.Graphics2D – 34ms
  • Image.getScaledInstance() – 235ms
  • Imgscalr – 143ms
  • サムナイレーター– 547ms
  • マーヴィン– 361ms

また、ターゲット画像の幅と高さを定義する際には、画像のアスペクト比に注意する必要があります。このようにすると、画像は元の比率を維持し、引き伸ばされません。

7. 結論

この記事では、Javaで画像のサイズを変更するいくつかの方法を説明しました。 また、サイズ変更プロセスに影響を与える可能性のあるさまざまな要因の数も学びました。

完全なコードサンプルは、GitHubから入手できます。