2

ここに、AffineTransform を使用して 90 度回転させたい寸法 2156x1728 の白黒の png ファイルがあります。結果の画像は、適切な比率を持っていません。ここにいくつかのサンプルコードがあります(pngファイルを BufferedImage に正常にロードした場合):

public BufferedImage transform(BufferedImage image){

    System.out.println("Input width: "+ image.getWidth());
    System.out.println("Input height: "+ image.getHeight());

    AffineTransform affineTransform = new AffineTransform();
    affineTransform.setToQuadrantRotation(1, image.getWidth() / 2, image.getHeight() / 2);

    AffineTransformOp opRotated = new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_BILINEAR);
    BufferedImage transformedImage = opRotated.createCompatibleDestImage(image, image.getColorModel());
    System.out.println("Resulting width: "+ transformedImage.getWidth());
    System.out.println("Resulting height: "+ transformedImage.getHeight());

    transformedImage = opRotated.filter(image, transformedImage);
    return transformedImage;
}

したがって、出力は次のようになります。

入力幅:2156

入力高さ: 1728

結果の幅: 1942

結果の高さ: 1942

回転がこのようなまったく無関係な次元を返すのはなぜですか?

4

3 に答える 3

6

私はこれのプロではありませんが、正しいサイズの BufferedImage を作成しないのはなぜですか? また、回転の中心が正しくないことに注意してください。[w/2, w/2] または [h/2, h/2] (w は幅、h は高さ) の中心で回転する必要があります。 、および画像の相対的な高さと幅。例えば:

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

public class RotateImage {
   public static final String IMAGE_PATH = "http://duke.kenai.com/"
         + "models/Duke3DprogressionSmall.jpg";

   public static void main(String[] args) {
      try {
         URL imageUrl = new URL(IMAGE_PATH);
         BufferedImage img0 = ImageIO.read(imageUrl);
         ImageIcon icon0 = new ImageIcon(img0);

         int numquadrants = 1;
         BufferedImage img1 = transform(img0, numquadrants );
         ImageIcon icon1 = new ImageIcon(img1);

         JOptionPane.showMessageDialog(null, new JLabel(icon0));
         JOptionPane.showMessageDialog(null, new JLabel(icon1));

      } catch (MalformedURLException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }

   public static BufferedImage transform(BufferedImage image, int numquadrants) {
      int w0 = image.getWidth();
      int h0 = image.getHeight();
      int w1 = w0;
      int h1 = h0;

      int centerX = w0 / 2;
      int centerY = h0 / 2;

      if (numquadrants % 2 == 1) {
         w1 = h0;
         h1 = w0;
      }

      if (numquadrants % 4 == 1) {
         if (w0 > h0) {
            centerX = h0 / 2;
            centerY = h0 / 2;
         } else if (h0 > w0) {
            centerX = w0 / 2;
            centerY = w0 / 2;
         }
         // if h0 == w0, then use default
      } else if (numquadrants % 4 == 3) {
         if (w0 > h0) {
            centerX = w0 / 2;
            centerY = w0 / 2;
         } else if (h0 > w0) {
            centerX = h0 / 2;
            centerY = h0 / 2;
         }
         // if h0 == w0, then use default
      }

      AffineTransform affineTransform = new AffineTransform();
      affineTransform.setToQuadrantRotation(numquadrants, centerX, centerY);

      AffineTransformOp opRotated = new AffineTransformOp(affineTransform,
            AffineTransformOp.TYPE_BILINEAR);

      BufferedImage transformedImage = new BufferedImage(w1, h1,
            image.getType());

      transformedImage = opRotated.filter(image, transformedImage);
      return transformedImage;
   }
}

編集1
あなたが尋ねた:

[w/2, w/2] または [h/2, h/2] でなければならない理由を説明してもらえますか?

これを最もよく説明するには、長方形を視覚化して物理的に操作するのが最善です。

長方形の紙を切り取り、左上隅が紙の左上隅になるように紙の上に置きます。これが画面上の画像です。次に、新しい左上隅が紙の左上隅に重なるように、その長方形の 1 象限または 3 象限をどこで回転させる必要があるかを確認します。[w/2, w/2] または [w/2] または[h/2, h/2]。

于 2012-01-03T23:28:11.447 に答える
5

上記の解決策には、画像の幅と高さに問題がありました。以下のコードは w > h || とは無関係です。h>w

public static BufferedImage rotateImage(BufferedImage image, int quadrants) {

    int w0 = image.getWidth();
    int h0 = image.getHeight();
    int w1 = w0;
    int h1 = h0;
    int centerX = w0 / 2;
    int centerY = h0 / 2;

    if (quadrants % 2 == 1) {
        w1 = h0;
        h1 = w0;
    }

    if (quadrants % 4 == 1) {
        centerX = h0 / 2;
        centerY = h0 / 2;
    } else if (quadrants % 4 == 3) {
        centerX = w0 / 2;
        centerY = w0 / 2;
    }

    AffineTransform affineTransform = new AffineTransform();
    affineTransform.setToQuadrantRotation(quadrants, centerX, centerY);
    AffineTransformOp opRotated = new AffineTransformOp(affineTransform,
            AffineTransformOp.TYPE_BILINEAR);
    BufferedImage transformedImage = new BufferedImage(w1, h1,
            image.getType());
    transformedImage = opRotated.filter(image, transformedImage);

    return transformedImage;

}
于 2012-09-07T11:53:26.797 に答える