【问题标题】:Java image rotation with AffineTransform outputs black image, but works well when resized使用 AffineTransform 的 Java 图像旋转输出黑色图像,但在调整大小时效果很好
【发布时间】:2012-03-19 22:25:21
【问题描述】:

我只是想将 JPG 文件旋转 90 度。但是我的代码输出的图像 (BufferedImage) 完全是黑色的。

复制方法如下:(下载3.jpg here

private static BufferedImage transform(BufferedImage originalImage) {
    BufferedImage newImage = null;
    AffineTransform tx = new AffineTransform();
    tx.rotate(Math.PI / 2, originalImage.getWidth() / 2, originalImage.getHeight() / 2);

    AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BICUBIC);
    newImage = op.filter(originalImage, newImage);

    return newImage;
}

public static void main(String[] args) throws Exception {
    BufferedImage bi = transform(ImageIO.read(new File(
            "3.jpg")));
    ImageIO.write(bi, "jpg", new File("out.jpg"));

}

这里有什么问题?

(如果我将此黑色输出BufferedImage 提供给图像调整器库,它会很好地调整大小,原始图像仍然存在。)

【问题讨论】:

    标签: java graphics2d


    【解决方案1】:

    将新的 BufferedImage 传递给 filter() 方法,而不是让它创建自己的作品(不是完全黑的)。

    此外,转换似乎没有正常工作,图像最终在目标位置偏移。我可以通过手动应用必要的翻译来修复它,注意这些工作以相反的顺序进行,在目标图像中,宽度 = 旧高度,高度 = 旧宽度。

    AffineTransform tx = new AffineTransform();
    
    // last, width = height and height = width :)
    tx.translate(originalImage.getHeight() / 2,originalImage.getWidth() / 2);
    tx.rotate(Math.PI / 2);
    // first - center image at the origin so rotate works OK
    tx.translate(-originalImage.getWidth() / 2,-originalImage.getHeight() / 2);
    
    AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
    
    // new destination image where height = width and width = height.
    BufferedImage newImage =new BufferedImage(originalImage.getHeight(), originalImage.getWidth(), originalImage.getType());
    op.filter(originalImage, newImage);
    

    filter() 的 javadoc 声明它将为您创建一个 BufferedImage,我仍然不确定为什么这不起作用,这里肯定有问题。

     If the destination image is null, a BufferedImage is created with the source ColorModel.
    

    【讨论】:

      【解决方案2】:

      如果您愿意使用 3rd 方库(非常小,只有 2 个类)imgscalr 可以在一行中为您完成此操作,同时解决不同图像类型可能导致的所有过滤器陷阱。

      使用Scalr.rotate(...) 看起来像这样:

      BufferedImage newImage = Scalr.rotate(originalImage, Rotation.CW_90);
      

      如果这种旋转是处理图像的大型应用程序的一部分,您甚至可以根据需要异步执行此操作 (AsyncScalr class)。

      imgscalr 在 Apache 2 许可下,所有源代码都可用;如果您更愿意自己动手​​,请阅读code for the rotate() method,我已经记录了在 Java2D 中使用过滤器时可能出现的所有问题。

      希望有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-15
        • 2018-07-20
        • 1970-01-01
        • 2019-07-11
        • 2017-08-22
        • 2012-07-14
        • 1970-01-01
        相关资源
        最近更新 更多