How to rotate JPEG images based on the orientation metadata?

后端 未结 8 1825
轻奢々
轻奢々 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 13:19

    Based on the answers of Antoine Martin I created an own class for correcting the orientation of a given jpeg image (in my case as an input stream) based on the exif information of the image. With his solution I had the problem, that the colors of the resulting image were wrong, therefore I created this one. For retrieving the metadata of the image I used the metadata-extractor library.

    I hope it will help some people.

    public class ImageOrientationUtil {
    
    /**
     * Checks the orientation of the image and corrects it if necessary.
     * 

    If the orientation of the image does not need to be corrected, no operation will be performed.

    * @param inputStream * @return * @throws ImageProcessingException * @throws IOException * @throws MetadataException */ public static BufferedImage correctOrientation(InputStream inputStream) throws ImageProcessingException, IOException, MetadataException { Metadata metadata = ImageMetadataReader.readMetadata(inputStream); if(metadata != null) { if(metadata.containsDirectoryOfType(ExifIFD0Directory.class)) { // Get the current orientation of the image Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); int orientation = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION); // Create a buffered image from the input stream BufferedImage bimg = ImageIO.read(inputStream); // Get the current width and height of the image int[] imageSize = {bimg.getWidth(), bimg.getHeight()}; int width = imageSize[0]; int height = imageSize[1]; // Determine which correction is needed AffineTransform t = new AffineTransform(); switch(orientation) { case 1: // no correction necessary skip and return the image return bimg; case 2: // Flip X t.scale(-1.0, 1.0); t.translate(-width, 0); return transform(bimg, t); case 3: // PI rotation t.translate(width, height); t.rotate(Math.PI); return transform(bimg, t); case 4: // Flip Y t.scale(1.0, -1.0); t.translate(0, -height); return transform(bimg, t); case 5: // - PI/2 and Flip X t.rotate(-Math.PI / 2); t.scale(-1.0, 1.0); return transform(bimg, t); case 6: // -PI/2 and -width t.translate(height, 0); t.rotate(Math.PI / 2); return transform(bimg, t); case 7: // PI/2 and Flip t.scale(-1.0, 1.0); t.translate(height, 0); t.translate(0, width); t.rotate( 3 * Math.PI / 2); return transform(bimg, t); case 8: // PI / 2 t.translate(0, width); t.rotate( 3 * Math.PI / 2); return transform(bimg, t); } } } return null; } /** * Performs the tranformation * @param bimage * @param transform * @return * @throws IOException */ private static BufferedImage transform(BufferedImage bimage, AffineTransform transform) throws IOException { // Create an transformation operation AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BICUBIC); // Create an instance of the resulting image, with the same width, height and image type than the referenced one BufferedImage destinationImage = new BufferedImage( bimage.getWidth(), bimage.getHeight(), bimage.getType() ); op.filter(bimage, destinationImage); return destinationImage; } }

提交回复
热议问题