blog5开发:上传图片缩放旋转了90度

最近发现上传的图片有时候会被旋转90度,奇怪的是本地看都是正常的。。在上一家公司也碰到过这种问题,不过是wap端,其实都一样。

一开始以为是GraphicMagick的strip参数的原因,我当时理解是strip去掉了照片的exif信息,导致无法读取正确的exif信息,从而引起了照片旋转,但我去掉了strip参数以及其他所有的参数,就光光的:

gm convert f:/1.jpg f:/2.jpg

用浏览器打开2.jpg,依旧存在90度的问题。

无奈之下搜索了一番,在 http://jeromebelleman.gitlab.io/posts/graphics/rotating/ 这里发现gm还有一个 -auto-orient参数:

Photos you take with a camera will include tags describing extra information about the picture, such as when it was taken, sometimes where, how the camera was set up and, very usefully, in which orientation – landscape or portrait. However, web browsers may not take those tags into account and you will want to literally turn portraits 90°. Luckily, GraphicsMagick can use Exif data and offers the -auto-orient option to automatically rotate the image according to it. This is convenient because you don't have to first sort landscapes from portraits – you can treat all your photos the same way and GraphicsMagick will do the right thing:

加上这个参数之后再缩放,终于发现照片不再旋转90度了。

如果采用纯java来解决这个问题,可以参考 https://stackoverflow.com/questions/21951892/how-to-determine-and-auto-rotate-images

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;

import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifIFD0Directory;
import com.drew.metadata.jpeg.JpegDirectory;

public class Main {

    private static String inFilePath = "C:\\Users\\TapasB\\Desktop\\MHIS031522.jpg";
    private static String outFilePath = "C:\\Users\\TapasB\\Desktop\\MHIS031522-rotated.jpg";

    public static void main(String[] args) throws Exception {
        File imageFile = new File(inFilePath);
        BufferedImage originalImage = ImageIO.read(imageFile);

        Metadata metadata = ImageMetadataReader.readMetadata(imageFile);
        ExifIFD0Directory exifIFD0Directory = metadata.getDirectory(ExifIFD0Directory.class);
        JpegDirectory jpegDirectory = (JpegDirectory) metadata.getDirectory(JpegDirectory.class);

        int orientation = 1;
        try {
            orientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        int width = jpegDirectory.getImageWidth();
        int height = jpegDirectory.getImageHeight();

        AffineTransform affineTransform = new AffineTransform();

        switch (orientation) {
        case 1:
            break;
        case 2: // Flip X
            affineTransform.scale(-1.0, 1.0);
            affineTransform.translate(-width, 0);
            break;
        case 3: // PI rotation
            affineTransform.translate(width, height);
            affineTransform.rotate(Math.PI);
            break;
        case 4: // Flip Y
            affineTransform.scale(1.0, -1.0);
            affineTransform.translate(0, -height);
            break;
        case 5: // - PI/2 and Flip X
            affineTransform.rotate(-Math.PI / 2);
            affineTransform.scale(-1.0, 1.0);
            break;
        case 6: // -PI/2 and -width
            affineTransform.translate(height, 0);
            affineTransform.rotate(Math.PI / 2);
            break;
        case 7: // PI/2 and Flip
            affineTransform.scale(-1.0, 1.0);
            affineTransform.translate(-height, 0);
            affineTransform.translate(0, width);
            affineTransform.rotate(3 * Math.PI / 2);
            break;
        case 8: // PI / 2
            affineTransform.translate(0, width);
            affineTransform.rotate(3 * Math.PI / 2);
            break;
        default:
            break;
        }       

        AffineTransformOp affineTransformOp = new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_BILINEAR);  
        BufferedImage destinationImage = new BufferedImage(originalImage.getHeight(), originalImage.getWidth(), originalImage.getType());
        destinationImage = affineTransformOp.filter(originalImage, destinationImage);
        ImageIO.write(destinationImage, "jpg", new File(outFilePath));
    }
}