How to rotate JPEG images based on the orientation metadata?

后端 未结 8 1822
轻奢々
轻奢々 2020-11-27 12:30

I have some server code that is generating thumbnails when an image is uploaded. The issue is that when the image was taken and the camera/device was rotated, the thumbnail

8条回答
  •  我在风中等你
    2020-11-27 12:55

    If you want to rotate your images, I would suggest to use the metadata extractor library http://code.google.com/p/metadata-extractor/. You can get the image information with the following code:

    // Inner class containing image information
    public static class ImageInformation {
        public final int orientation;
        public final int width;
        public final int height;
    
        public ImageInformation(int orientation, int width, int height) {
            this.orientation = orientation;
            this.width = width;
            this.height = height;
        }
    
        public String toString() {
            return String.format("%dx%d,%d", this.width, this.height, this.orientation);
        }
    }
    
    
    public static ImageInformation readImageInformation(File imageFile)  throws IOException, MetadataException, ImageProcessingException {
        Metadata metadata = ImageMetadataReader.readMetadata(imageFile);
        Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
        JpegDirectory jpegDirectory = metadata.getFirstDirectoryOfType(JpegDirectory.class);
    
        int orientation = 1;
        try {
            orientation = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
        } catch (MetadataException me) {
            logger.warn("Could not get orientation");
        }
        int width = jpegDirectory.getImageWidth();
        int height = jpegDirectory.getImageHeight();
    
        return new ImageInformation(orientation, width, height);
    }
    

    Then given the orientation you retrieve, you can rotate and/or flip the image to the right orientation. The Affine transform for the EXIF orientation is given by the following method:

    // Look at http://chunter.tistory.com/143 for information
    public static AffineTransform getExifTransformation(ImageInformation info) {
    
        AffineTransform t = new AffineTransform();
    
        switch (info.orientation) {
        case 1:
            break;
        case 2: // Flip X
            t.scale(-1.0, 1.0);
            t.translate(-info.width, 0);
            break;
        case 3: // PI rotation 
            t.translate(info.width, info.height);
            t.rotate(Math.PI);
            break;
        case 4: // Flip Y
            t.scale(1.0, -1.0);
            t.translate(0, -info.height);
            break;
        case 5: // - PI/2 and Flip X
            t.rotate(-Math.PI / 2);
            t.scale(-1.0, 1.0);
            break;
        case 6: // -PI/2 and -width
            t.translate(info.height, 0);
            t.rotate(Math.PI / 2);
            break;
        case 7: // PI/2 and Flip
            t.scale(-1.0, 1.0);
            t.translate(-info.height, 0);
            t.translate(0, info.width);
            t.rotate(  3 * Math.PI / 2);
            break;
        case 8: // PI / 2
            t.translate(0, info.width);
            t.rotate(  3 * Math.PI / 2);
            break;
        }
    
        return t;
    }
    

    The rotation of the image would be done by the following method:

    public static BufferedImage transformImage(BufferedImage image, AffineTransform transform) throws Exception {
    
        AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BICUBIC);
    
        BufferedImage destinationImage = op.createCompatibleDestImage(image, (image.getType() == BufferedImage.TYPE_BYTE_GRAY) ? image.getColorModel() : null );
        Graphics2D g = destinationImage.createGraphics();
        g.setBackground(Color.WHITE);
        g.clearRect(0, 0, destinationImage.getWidth(), destinationImage.getHeight());
        destinationImage = op.filter(image, destinationImage);
        return destinationImage;
    }
    

    In a server environment, don't forget to run with -Djava.awt.headless=true

提交回复
热议问题