使用 imagemagick 旋转

查看照片 EXIF 信息,Exif 中的图片旋转信息储存在Orientation中。

identify -verbose xxx.jpg

自动识别并旋转图片

convert xxx.jpg -auto-orient yyy.jpg

Orientation 可能的值

Value0th Row0th Column逆时针旋转的角度
1topleft side0
2*topright side-
3bottomright side180
4*bottomleft side-
5*left sidetop-
6right sidetop90
7*right sidebottom-
8left sidebottom270

使用 JS 旋转

使用exif-js可以获取到相关 Exif 信息。

<!DOCTYPE html>
<html>
  <head>
  	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  	<title>图片旋转demo</title>
	<style>
	.img-90 {
		transform:rotate(90deg);
		-ms-transform:rotate(90deg); 	/* IE 9 */
		-moz-transform:rotate(90deg); 	/* Firefox */
		-webkit-transform:rotate(90deg); /* Safari 和 Chrome */
		-o-transform:rotate(90deg); 	/* Opera */
	}
	</style>
	<script type="text/javascript" src="./static/thirdparty/exif-js.js"></script>
	<script>
	window.onload=getExif;
	
	var Orientations = {
		'1': 0,
		'3': 180,
		'6': 90,
		'8': 270
	};
	function getExif() {
		var img1 = document.getElementById("img1");
		EXIF.getData(img1, function() {
			var orientation = EXIF.getTag(this, "Orientation");
			var makeAndModel = document.getElementById("orientation1");
			makeAndModel.innerHTML = Orientations[orientation];
			document.getElementById('img1').classList.add('img-' + Orientations[orientation]);
		});
	}
	</script>
  </head>
  <body>
    <div style="border: 1px solid black;width:300px;margin-right:5px;float: left;">
		<img  id="img1" src="./static/images/fp.png" style="max-width:300px" />
		<pre>旋转角度: <span id="orientation1"></span></pre>
    </div>
  </body>
</html>

旋转时可以通过以上css3方式简易实现,还可以通过canvas绘制实现。

使用 Java 旋转

import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifIFD0Directory;
import org.apache.commons.lang3.StringUtils;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class ImageRotateDemo {

    /**
     * 对图片进行旋转
     *
     * @param src
     *            被旋转图片
     * @param angel
     *            旋转角度
     * @return 旋转后的图片
     */
    public static BufferedImage rotate(Image src, int angel) {
        int src_width = src.getWidth(null);
        int src_height = src.getHeight(null);
        // 计算旋转后图片的尺寸
        Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), angel);
        BufferedImage res = null;
        res = new BufferedImage(rect_des.width, rect_des.height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = res.createGraphics();
        // 进行转换
        g2.translate((rect_des.width - src_width) / 2, (rect_des.height - src_height) / 2);
        g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);

        g2.drawImage(src, null, null);
        return res;
    }

    /**
     * 计算旋转后的图片
     *
     * @param src
     *            被旋转的图片
     * @param angel
     *            旋转角度
     * @return 旋转后的图片
     */
    public static Rectangle CalcRotatedSize(Rectangle src, int angel) {
        // 如果旋转的角度大于90度做相应的转换
        if (angel >= 90) {
            if (angel / 90 % 2 == 1) {
                int temp = src.height;
                src.height = src.width;
                src.width = temp;
            }
            angel = angel % 90;
        }

        double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
        double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
        double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
        double angel_dalta_width = Math.atan((double) src.height / src.width);
        double angel_dalta_height = Math.atan((double) src.width / src.height);

        int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_width));
        int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_height));
        int des_width = src.width + len_dalta_width * 2;
        int des_height = src.height + len_dalta_height * 2;
        return new Rectangle(new Dimension(des_width, des_height));
    }

    /**
     * 获得图片调整角度
     * 
     * @param imgFile
     * @return
     */
    public static Integer getImgRotateAngle(String imgFile) {
        Integer angel = 0;
        Metadata metadata = null;
        try {
            if (StringUtils.isBlank(imgFile))
                return angel;
            File _img_file_ = new File(imgFile);
            if (!_img_file_.exists())
                return angel;
            metadata = ImageMetadataReader.readMetadata(_img_file_);
            Directory directory = metadata.getDirectory(ExifIFD0Directory.class);
            if (directory != null && directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
                int orientation = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
                // 原图片的方向信息
                if (6 == orientation) {
                    // 6旋转90
                    angel = 90;
                } else if (3 == orientation) {
                    // 3旋转180
                    angel = 180;
                } else if (8 == orientation) {
                    // 8旋转90
                    angel = 270;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return angel;
    }

    /**
     * 调整图片角度
     * 
     * @param imgFile
     */
    public static void rotateImage(String imgFile) {
        try {
            if (StringUtils.isBlank(imgFile)) {
                File _img_file_ = new File(imgFile);
                if (_img_file_.exists()) {
                    Integer angel = getImgRotateAngle(imgFile);
                    if (angel == 0)
                        return;
                    BufferedImage src = ImageIO.read(_img_file_);
                    BufferedImage des = rotate(src, angel);
                    ImageIO.write(des, "jpg", _img_file_);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        String fromPic = "D:\\MyProject\\Test\\resource\\fp.png";
        // rotateImage(file);

        Integer angel = getImgRotateAngle(fromPic);
        System.out.println(angel);
        if (angel > 0) {
            BufferedImage src = ImageIO.read(new File(fromPic));
            // 顺时针旋转270度
            BufferedImage des3 = rotate(src, 270);
            ImageIO.write(des3, "png", new File("D:\\MyProject\\Test\\resource\\fp_270.png"));
        }
        System.out.println("==End==");
    }
}

Q.E.D.


Think Big, Act Small