AffineTransform截断图像 [英] AffineTransform truncates image
问题描述
我有一个图像,我必须旋转45度,90度,135度,180度。我在做什么:
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:
问题http: //img32.imageshack.us/img32/3328/resultcs.png
我用谷歌搜索了这个问题并找到了这个问题的解决方案: AffineTransform截断图片,我有什么不对?但我完全不明白它只适用于象限。我试图将目标的宽度和高度相乘两倍,但它失败了:
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:
另一个失败http://img401.imageshack.us/img401/2417/result2a.png
如何解决这个问题?目标图像不应具有任何额外的(对角线旋转所需的除外)空白或截断区域。角度问题(0 == 180或顺时针方向)并不重要。
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.
感谢您的帮助。
推荐答案
编辑:现在它适用于一般情况。
旋转是围绕中心,并且中心位于目标图像中与源图像中相同的位置(正确行为)。
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).
我已修改您的代码以进行转换源图像矩形,以便我们可以轻松获得新的尺寸/图像偏移。这用于构造正确尺寸的目的地 BufferedImage
,并将翻译附加到 AffineTransform
,以便图像center位于目标图像的中心。
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截断图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!