当前位置: 首页 > 面试题库 >

AffineTransform会截断图像,我该怎么办?

宰父单弓
2023-03-14
问题内容

我这里有一个尺寸为2156x1728的黑白png文件,我想使用AffineTransform旋转90度。生成的图像比例不正确。这是一些示例代码(假设我已将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

旋转如何返回如此完全无关的尺寸?


问题答案:

我不是专业人士,但是为什么不创建一个正确大小的BufferedImage?另请注意,您的旋转中心不正确。您将需要旋转[w / 2,w / 2]或[h /
2,h / 2]的中心(w是宽度,h是高度),具体取决于要旋转到的象限,是1还是3 ,以及图片的相对高度和宽度。例如:

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]或[h / 2,h / 2]。



 类似资料:
  • 问题内容: 我上课了。在这个类中,我有一个类型的变量。更重要的是,我有WorldMap重写功能的类: 函数看起来像这样: 它只需要1)旋转飞机(飞机对象内部的BufferedImage)2)画他。 我的Airplane.rotateAirplane()函数如下所示: 我运行我的程序时,ofc仅绘制对象。当我删除此车道时 我也有我的飞机,但是没有旋转。 问题答案: 主要的问题(我可以看到)是上下文的

  • 问题内容: 我的网站几乎完成了,除了最后一部分,我需要使图库页面支持ajax才能使用Ajax更改页码。 图库页面视图: Dajax / Dajaxice的记录不是很好…我只需要显示一些图像即可。 问题答案: 这是使用Dajax / Dajaxice的方法,这是为了在Django中简化AJAX: 根据文档安装Dajaxice和Dajax。文档似乎没有提及它,但是您也可以使用,即 pip instal

  • 问题内容: 我正在使用具有“很高”的xlabel的位置绘制数据集(这是在TeX中渲染的公式,其中包含一个分数,因此其高度等于几行文本)。 无论如何,当我绘制数字时,公式的底部总是被切除。更改图形大小似乎无济于事,而且我还无法弄清楚如何将x轴“向上”移动以为xlabel腾出空间。诸如此类的东西将是一个合理的临时解决方案,但最好的办法是使matplotlib自动识别标签被切断并相应调整大小。 这是我的

  • 问题内容: 我认为这个问题与Zope无关。尽管如此,我将解释我要做什么: 我在Zope中使用PUT_factory通过FTP将图像上传到ZODB。上载的图像另存为Zope图像,位于新创建的容器对象中。效果很好,但是如果图像超过特定大小(宽度和高度),我想调整图像的大小。所以我正在使用PIL的缩略图功能来调整它们的大小,即200x200。只要上传的图像相对较小,此方法就可以正常工作。我没有检查出确切