Java で画像を回転させる

Rupam Yadav 2023年10月12日
  1. Java で BufferedImageGraphics2D.rotate() を使用して画像を回転させる
  2. Java でアフィン変換を使用して画像を回転させる
Java で画像を回転させる

この記事では、2つのネイティブな方法を使用して Java で画像を回転させる方法を紹介します。

Java で BufferedImageGraphics2D.rotate() を使用して画像を回転させる

画像を回転させる最初のメソッドには、AWT パッケージに付属する BufferedImage および Graphics2d クラスの使用が含まれます。以下では、パラメータとして BufferedImage オブジェクトを受け取り、回転した BufferedImage オブジェクトを返す関数 rotateImage() を作成します。

rotateImage() では、getWidth()getHeight()、および getType() メソッドを使用して、画像の幅、高さ、およびタイプを取得します。ここで、BufferedImage() コンストラクターを呼び出し、3つの変数を引数として渡すと、BufferedImage オブジェクト newImageFromBuffer が返されます。

Graphics2D オブジェクト graphics2D を返す createGraphics() メソッドを使用して、新しい回転画像を作成します。このオブジェクトを使用して、3つの引数を取る rotate() 関数を呼び出します。1つ目は、画像を 90 度回転させたいときに、Math.radians(90) を渡す角度です。2 番目と 3 番目の引数は、x 座標と y 座標です。

最後に、graphics2D.drawImage() を呼び出して、回転した画像を描画します。これは、BufferedImage オブジェクト、適用するフィルター、および x 座標と y 座標の 4つの引数を取ります。次に、newImageFromBuffer オブジェクトを返します。

main 関数では、File を使用してファイルを読み取り、ImageIO.read() を使用してそれを BufferedImage オブジェクトに変換します。次に、rotateImage() 関数を呼び出し、返された BufferedImage オブジェクトを渡し、回転した BufferedImage オブジェクトを格納します。回転した画像ができたので、FileImageIO.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 で画像を回転-元の画像

回転画像:

Java で画像を回転-回転した画像

Java でアフィン変換を使用して画像を回転させる

この例では、元の品質を失うことなく、元の 2D 座標から他の 2D 座標に画像を線形にマッピングする AffineTransform クラスを使用します。次のプログラムでは、3つのメソッドを使用します。1つは他の関数を読み取って呼び出す方法、2つ目は画像を時計回りに回転させる方法、最後の関数は画像を反時計回りに回転させる方法です。

rotateImage() 関数では、new File() を使用して画像を読み取り、ImageIO.read() を使用して BufferedImage オブジェクトに変換します。次に、元の画像のプロパティを保持する別の BufferedImage オブジェクトを作成し、それを output と呼びます。次に、rotateImageClockWise() メソッドを呼び出し、AffineTransorm クラスのオブジェクトを返す元の BufferedImage を渡します。

rotateImageClockWise()image を受け取り、高さと幅を取得します。AffineTransform オブジェクト AffineTransform を作成し、それを使用して rotate() メソッドを呼び出します。rotate() では、3つの引数を渡します。最初はラジアンで測定された回転角です。ここでは Math.PI / 2 を渡します。最後の 2つの引数は、画像の幅と高さの半分である x 座標と y 座標です。

ここで、画像が回転するときに、x 方向に回転する距離と y 方向に回転する距離の 2つの引数を取る translate() 関数を使用して、画像を新しい座標に変換します。(imageWidth - imageHeight) / 2 を使用して x 引数と y 引数を計算します。

画像を反時計回りに回転させるには、rotateImageClockWise() の代わりに rotate() でメソッド rotateImageCounterClockwise() を呼び出すことができます。

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();
    }
  }
}

出力:

元の画像:

Java で画像を回転-元の画像

時計回りに回転した画像:

Java で画像を回転-時計回りに回転した画像

反時計回りに回転した画像:

Java で画像を回転-反時計回りに回転した画像

著者: Rupam Yadav
Rupam Yadav avatar Rupam Yadav avatar

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

関連記事 - Java Image