AffineTransform truncates image

前端 未结 2 817
一个人的身影
一个人的身影 2021-01-16 11:25

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\"));
             


        
相关标签:
2条回答
  • 2021-01-16 11:51

    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));
    
    0 讨论(0)
  • 2021-01-16 12:09

    I suggest to replace

    AffineTransformOp op = new AffineTransformOp(t, null);
    

    with

    AffineTransformOp op = new AffineTransformOp(t,  AffineTransformOp.TYPE_BILINEAR);
    

    It will improve a lot the quality of the output.

    0 讨论(0)
提交回复
热议问题