使用AffineTransform进行Java图像旋转会输出黑色图像,但在resize时效果很好
我只是想将JPG文件旋转90度。 但是我的代码输出完全黑色的图像( BufferedImage
)。
这是重现的方式:( 在这里下载3.jpg)
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
提供给图像缩放器库,它会很好地resize,原始图像仍然存在。)
将新的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个类)的想法持开放态度,imgscalr可以在一行中为您完成此任务,同时解决不同图像类型可能导致的所有filter问题。
使用Scalr.rotate(…)看起来像这样:
BufferedImage newImage = Scalr.rotate(originalImage, Rotation.CW_90);
如果此旋转是处理图像的较大应用程序的一部分,则甚至可以在需要时异步执行此操作( AsyncScalr类 )。
imgscalr是Apache 2许可证,所有来源都可用; 如果您想亲自自己动手,请仔细阅读rotate()方法的代码 ,我已经记录了在Java2D中使用filter时可能出现的所有问题。
希望有所帮助!