使用AffineTransform进行Java图像旋转会输出黑色图像,但在调整大小时效果很好

时间:2012-03-17 10:13:04

标签: java graphics2d

我只是想将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提供给图像缩放器库,它会很好地调整大小,原始图像仍然存在。)

2 个答案:

答案 0 :(得分:14)

将新的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.

答案 1 :(得分:5)

如果您对使用第三方库(非常小,只有2个类)的想法持开放态度imgscalr可以在一行中为您完成此任务,同时解决所有不同图像类型的过滤器问题原因。

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

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

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

imgscalr属于Apache 2许可证,所有来源均可用;如果你想亲自自己做,请阅读code for the rotate() method,我已经记录了在Java2D中使用过滤器时可能出现的所有问题。

希望有所帮助!