AffineTransform truncates image(AffineTransform 截断图像)
问题描述
我有一张图片,我必须将它旋转 45、90、135、180 度.我在做什么:
试试{BufferedImage src = ImageIO.read(new File("src.png"));双 ang = Math.toRadians(90);仿射变换 t = 新的仿射变换();t.setToRotation(ang, src.getWidth()/2, src.getHeight()/2);AffineTransformOp op = new AffineTransformOp(t, null);BufferedImage dst = new BufferedImage(src.getWidth(), src.getHeight(), src.getType());op.filter(src, dst);ImageIO.write(dst, "png", new File("output.png"));} 捕捉(异常前) { ex.printStackTrace();}
问题是图像改变了它的位置并超出了目标图像的范围:
我用谷歌搜索并在这个问题中找到了解决方案:
如何解决这个问题?目标图像不应有任何额外的(对角旋转所需的除外)空白或截断区域.角度问题(0 == 180 还是顺时针)并不重要.
感谢您的帮助.
现在它适用于一般情况.
围绕中心进行旋转,中心在目标图像中的位置与在源图像中的位置相同(正确的行为).
我已修改您的代码以转换源图像矩形,以便我们可以轻松获得新的尺寸/图像偏移量.这用于构造正确尺寸的目标 BufferedImage
,并将翻译附加到您的 AffineTransform
以便图像中心位于目标图像的中心.
BufferedImage src = ImageIO.read(new File(INPUT));int w = src.getWidth();int h = src.getHeight();仿射变换 t = 新的仿射变换();双 ang = Math.toRadians(35);t.setToRotation(ang, w/2d, h/2d);//源图像矩形点 [] 点 = {新点(0, 0),新点(w,0),新点(w,h),新点(0, h)};//转换为目标矩形t.transform(点, 0, 点, 0, 4);//获取目标矩形边界框点 min = new Point(points[0]);最大点 = 新点(点 [0]);for (int i = 1, n = points.length; i < n; i ++) {点 p = 点[i];双 pX = p.getX(), pY = p.getY();//更新最小/最大 xif (pX max.getX()) max.setLocation(pX, max.getY());//更新最小/最大 yif (pY max.getY()) max.setLocation(max.getX(), pY);}//确定新的宽度、高度w = (int) (max.getX() - min.getX());h = (int) (max.getY() - min.getY());//确定需要的翻译双 tx = min.getX();双 ty = min.getY();//附加所需的翻译AffineTransform 翻译 = 新的 AffineTransform();翻译.translate(-tx, -ty);t.preConcatenate(翻译);AffineTransformOp op = new AffineTransformOp(t, null);BufferedImage dst = new BufferedImage(w, h, src.getType());op.filter(src, dst);ImageIO.write(dst,png",新文件(输出));
I have an image and I have to rotate it by 45, 90, 135, 180 degrees. What I am doing:
try {
BufferedImage src = ImageIO.read(new File("src.png"));
double ang = Math.toRadians(90);
AffineTransform t = new AffineTransform();
t.setToRotation(ang, src.getWidth() / 2, src.getHeight() / 2);
AffineTransformOp op = new AffineTransformOp(t, null);
BufferedImage dst = new BufferedImage(src.getWidth(), src.getHeight(), src.getType());
op.filter(src, dst);
ImageIO.write(dst, "png", new File("output.png"));
} catch(Exception ex) { ex.printStackTrace();
}
The problem is that image changes its position and gets out of bounds of destination image:
I've googled this and found the solution in this question: AffineTransform truncates image, what do I wrong? But I quite don't understand it and it works only for quadrants. I've tried to multiply twice width and height of destination, but it failed:
How to fix this? The destination image shouldn't have any extra (except required for diagonal rotation) whitespace or truncated area. Angle problems (0 == 180 or is it clockwise) aren't important.
Thanks for any help.
Edit: Now it works for the general case.
The rotation is performed around the center, and the center is placed at the same position in the destination image as it was in the source image (correct behavior).
I've modified your code to transform the source image rectangle so we can easily get the new dimensions/image offset. This is used to construct a destination BufferedImage
of the correct dimensions, and to append a translation to your AffineTransform
so the image center is placed at the center of the destination image.
BufferedImage src = ImageIO.read(new File(INPUT));
int w = src.getWidth();
int h = src.getHeight();
AffineTransform t = new AffineTransform();
double ang = Math.toRadians(35);
t.setToRotation(ang, w / 2d, h / 2d);
// source image rectangle
Point[] points = {
new Point(0, 0),
new Point(w, 0),
new Point(w, h),
new Point(0, h)
};
// transform to destination rectangle
t.transform(points, 0, points, 0, 4);
// get destination rectangle bounding box
Point min = new Point(points[0]);
Point max = new Point(points[0]);
for (int i = 1, n = points.length; i < n; i ++) {
Point p = points[i];
double pX = p.getX(), pY = p.getY();
// update min/max x
if (pX < min.getX()) min.setLocation(pX, min.getY());
if (pX > max.getX()) max.setLocation(pX, max.getY());
// update min/max y
if (pY < min.getY()) min.setLocation(min.getX(), pY);
if (pY > max.getY()) max.setLocation(max.getX(), pY);
}
// determine new width, height
w = (int) (max.getX() - min.getX());
h = (int) (max.getY() - min.getY());
// determine required translation
double tx = min.getX();
double ty = min.getY();
// append required translation
AffineTransform translation = new AffineTransform();
translation.translate(-tx, -ty);
t.preConcatenate(translation);
AffineTransformOp op = new AffineTransformOp(t, null);
BufferedImage dst = new BufferedImage(w, h, src.getType());
op.filter(src, dst);
ImageIO.write(dst, "png", new File(OUTPUT));
这篇关于AffineTransform 截断图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:AffineTransform 截断图像


基础教程推荐
- “未找到匹配项"使用 matcher 的 group 方法时 2022-01-01
- 无法使用修饰符“public final"访问 java.util.Ha 2022-01-01
- 减少 JVM 暂停时间 >1 秒使用 UseConcMarkSweepGC 2022-01-01
- FirebaseListAdapter 不推送聊天应用程序的单个项目 - Firebase-Ui 3.1 2022-01-01
- 设置 bean 时出现 Nullpointerexception 2022-01-01
- Java Keytool 导入证书后出错,"keytool error: java.io.FileNotFoundException &拒绝访问" 2022-01-01
- 降序排序:Java Map 2022-01-01
- 如何使用 Java 创建 X509 证书? 2022-01-01
- Java:带有char数组的println给出乱码 2022-01-01
- 在 Libgdx 中处理屏幕的正确方法 2022-01-01