Java corrects the problem of automatic rotation and mirroring of uploaded images

Java corrects the problem of automatic rotation and mirroring of uploaded images

When you encounter a picture, it looks like the direction is positive, but it automatically rotates and mirrors after you open it with a specific tool.

After checking out this article: https://www.cnblogs.com/csonezp/p/5564809.html.
A sentence in the original text: It turns out that the camera adds an Orientation to the exif information of the picture, and then the picture browser will make compatibility with this attribute, so that the picture will be displayed in the form of a vertical picture. Let me give some explanations about the Orientation attribute.
Why do we see it correct on some software or browsers? It’s because these software and browsers automatically correct the picture.
However, our Java does not automatically correct this picture for us. When we use BufferImage to draw a picture, we find that the height is actually the opposite.

How to solve it?

Introduction

<dependency>
    <groupId>com.drewnoakes</groupId>
    <artifactId>metadata-extractor</artifactId>
    <version>2.7.0</version>
</dependency>

This package can help me get the exif information of the image.

///1. Get the metadata of the image
Metadata metadata = ImageMetadataReader.readMetadata(file);
// 2. The direction of image metadata processing
int orientation = 0;

for (Directory directory : metadata.getDirectories()) {<!-- -->
    // 3. Only the data of TAG_ORIENTATION is needed.
    if(directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)){<!-- -->
        for (Tag tag : directory.getTags()) {<!-- -->
            System.out.println(tag);
        }
        orientation = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
    }
}

// Output [Exif IFD0] Orientation - Right side, top (Rotate 90 CW)

Understanding

td>

EXIF Orientation Value Row #0 is: Column #0 is: The corresponding direction should How to correct
1 Top Left side No need to correct
2 Top Right side Flip horizontally (mirror)
3 Bottom Right side Vertical flip (rotate 180°)
4 Bottom Left side Flip horizontally + flip vertically
5 Left side Top Flip horizontally + rotate 90°
6 Right side Top Rotate 90°
7 Right side Bottom Flip horizontally + rotate 270°
8 Left side Bottom + rotate 270°

You can refer to the figure below to understand

Implementation

public class ImageRotate {<!-- -->

    /**
     * How to correct pictures
     *
     * @param srcImgPath
     */
    /**
     * Correct image rotation
     *
     * @param srcImgPath
     */
    public static void correctImg(String srcImgPath) {<!-- -->
        FileOutputStream fos = null;
        try {<!-- -->
            // Original Image
            File srcFile = new File(srcImgPath);
            // 1. Get correction
            RectifyDirection rotateAngle = getRectifyDirection(srcFile);
            // 2. Return directly without correction
            if(rotateAngle == null){<!-- -->
                return;
            }
            System.out.println(rotateAngle.angel + ":" + rotateAngle.isMirror);
            
            // original image cache
            BufferedImage srcImg = ImageIO. read(srcFile);

            // original width
            int imgWidth = srcImg. getWidth();
            // original height
            int imgHeight = srcImg. getHeight();

            // 3. If it is not vertical, it means that their width and height need to be swapped
            if (rotateAngle. angel != 180) {<!-- -->
                int temp = imgWidth;
                imgWidth = imgHeight;
                imgHeight = temp;
            }

            // Center point position
            double centerWidth = ((double) imgWidth) / 2;
            double centerHeight = ((double) imgHeight) / 2;

            //Image cache
            BufferedImage targetImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);

            // Rotate the corresponding angle
            Graphics2D g = targetImg.createGraphics();
            // 4. Rotate to the left based on the center point position
            g.rotate(Math.toRadians(rotateAngle.angel), centerWidth, centerHeight);
            // 5. After rotation, the width and height of the image will be replaced again.
            System.out.println(srcImg.getWidth());
            System.out.println(srcImg.getHeight());
            // 6. Here you need to find the original width and height after replacement and the existing width and height, and draw the picture from this coordinate
            int x = (imgWidth - srcImg.getWidth()) / 2;
            int y = (imgHeight - srcImg.getHeight()) / 2;
            g.drawImage(srcImg, x, y, null);
            g.dispose();
            // 7. Do you need to flip horizontally?
            if (rotateAngle.isMirror){<!-- -->
                BufferedImage tempImage = new BufferedImage(targetImg.getWidth(), targetImg.getHeight(), BufferedImage.TYPE_INT_RGB);
                g = tempImage.createGraphics();
                // Use AffineTransform for horizontal flipping
                AffineTransform transform = new AffineTransform();
                // 8. After panning the width of the current picture
                transform.translate(targetImg.getWidth() , 0);
                // 9. Zoom
                // Because the abscissa scale is -1, it is flipped horizontally
                // See the horizontal flipping picture for the flipping process.
                transform. scale(-1, 1);
                g.setTransform(transform);

                g.drawImage(targetImg,0, 0, null);
                g. dispose();
                targetImg = tempImage;
            }

            // output image
            fos = new FileOutputStream(new File(srcFile.getAbsolutePath() + "." + srcImgPath.substring(srcImgPath.lastIndexOf(".") + 1)));
            ImageIO.write(targetImg, srcImgPath.substring(srcImgPath.lastIndexOf(".") + 1), fos);
        } catch (Exception e) {<!-- -->
            e.printStackTrace();
        } finally {<!-- -->
            if (fos != null) {<!-- -->
                try {<!-- -->
                    fos. flush();
                    fos. close();
                } catch (Exception e) {<!-- -->
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Get correct direction
     * @param file
     * @return
     * @throwsException
     */
    public static RectifyDirection getRectifyDirection(File file) throws Exception {<!-- -->
        // 1. Get the metadata of the image
        Metadata metadata = ImageMetadataReader.readMetadata(file);
        // 2. The direction of image metadata processing
        int orientation = 0;
        
        for (Directory directory : metadata.getDirectories()) {<!-- -->
            // 3. Only the data of TAG_ORIENTATION is needed.
            if(directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)){<!-- -->
                for (Tag tag : directory.getTags()) {<!-- -->
                    System.out.println(tag);
                }
                orientation = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
            }
        }
        // 4. Create different processing methods according to different orientations
        switch (orientation){<!-- -->
            case 2:
                return new RectifyDirection(0,true);
            case 3:
                return new RectifyDirection(180,false);
            case 4:
                return new RectifyDirection(180, true);
            case 5:
                return new RectifyDirection(90,true);
            case 6:
                return new RectifyDirection(90,false);
            case 7:
                return new RectifyDirection(270,true);
            case 8:
                return new RectifyDirection(270,false);
            default:
                return null;
        }
    }
\t
    static class RectifyDirection{<!-- -->
        /**
         * angle
         */
        public int angel;
        /**
         * Whether to mirror
         */
        public boolean isMirror;

        public RectifyDirection(int angel, boolean isMirror) {<!-- -->
            this.angel = angel;
            this.isMirror = isMirror;
        }
    }
}

Move coordinates after rotation

Flip horizontally