Exif信息 处理图片上传时翻转问题

java处理旋转角度的图片

Java读取图片EXIF信息的方法:

首先介绍一下什么是EXIF,EXIF是Exchangeable Image File的缩写,这是一种专门为数码相机照片设定的格式。这种格式可以用来记录数字照片的属性信息,例如相机的品牌及型号、相片的拍摄时间、拍摄时所设置 的光圈大小、快门速度、ISO等等信息。除此之外它还能够记录拍摄数据,以及照片格式化方式,这样就可以输出到兼容EXIF格式的外设上,例如照片打印机 等。

目前最常见的支持EXIF信息的图片格式是JPG,很多的图像工具都可以直接显示图片的EXIF信息,包括现在的一些著名的相册网站也提供页面用于 显示照片的EXIF信息。本文主要介绍Java语言如何读取图像的EXIF信息,包括如何根据EXIF信息对图像进行调整以适合用户浏览。

目前最简单易用的EXIF信息处理的Java包是Drew Noakes写的metadata-extractor,需要注意的是,并不是每个JPG图像文件都包含有EXIF信息,你可以在Windows资源管理器单击选中图片后,如果该图片包含EXIF信息,则会在属性->摘要中显示出来。

首先导入依赖,高版本已不支持,

    <dependency>
        <groupId>com.drewnoakes</groupId>
        <artifactId>metadata-extractor</artifactId>
        <version>2.4.0-beta-1</version>
    </dependency>

打包需要注意依赖无法打入需要手动打入

     <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <encoding>UTF-8</encoding>
                <compilerArguments>
                    <verbose />
                    <bootclasspath>${java.home}\lib\rt.jar${path.separator}${java.home}\lib\jce.jar${path.separator}</bootclasspath>
                </compilerArguments>
            </configuration>
        </plugin>

旋转工具类

下面展示处理代码工具类`。

public class RotateImageUtil {

    /**
     *
     * @param bufferedImage
     *            图片
     * @param angel
     *            旋转角度
     * @return
     */
    public static BufferedImage rotateImage(BufferedImage bufferedImage, int angel,int imageWidth ,int imageHeight ) {
        if (bufferedImage == null) {
            return null;
        }
        if (angel < 0) {
            // 将负数角度,纠正为正数角度
            angel = angel + 360;
        }
        // 计算重新绘制图片的尺寸
        Rectangle rectangle = calculatorRotatedSize(new Rectangle(new Dimension(imageWidth, imageHeight)), angel);
        // 获取原始图片的透明度
        int type = bufferedImage.getColorModel().getTransparency();
        BufferedImage newImage = null;
        newImage = new BufferedImage(rectangle.width, rectangle.height, type);
        Graphics2D graphics = newImage.createGraphics();
        // 平移位置
        graphics.translate((rectangle.width - imageWidth) / 2, (rectangle.height - imageHeight) / 2);
        // 旋转角度
        graphics.rotate(Math.toRadians(angel), imageWidth / 2, imageHeight / 2);
        // 绘图
        graphics.drawImage(bufferedImage, null, null);
        return newImage;
    }

    /**
     * 旋转图片
     *
     * @param image
     *            图片
     * @param angel
     *            旋转角度
     * @return
     */
    public static BufferedImage rotateImage(Image image, int angel) {
        if (image == null) {
            return null;
        }
        if (angel < 0) {
            // 将负数角度,纠正为正数角度
            angel = angel + 360;
        }
        int imageWidth = image.getWidth(null);
        int imageHeight = image.getHeight(null);
        Rectangle rectangle = calculatorRotatedSize(new Rectangle(new Dimension(imageWidth, imageHeight)), angel);
        BufferedImage newImage = null;
        newImage = new BufferedImage(rectangle.width, rectangle.height, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = newImage.createGraphics();
        // transform
        graphics.translate((rectangle.width - imageWidth) / 2, (rectangle.height - imageHeight) / 2);
        graphics.rotate(Math.toRadians(angel), imageWidth / 2, imageHeight / 2);
        graphics.drawImage(image, null, null);
        return newImage;
    }

    /**
     * 计算旋转后的尺寸
     *
     * @param src
     * @param angel
     * @return
     */
    private static Rectangle calculatorRotatedSize(Rectangle src, int angel) {
        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 java.awt.Rectangle(new Dimension(des_width, des_height));
    }
    /**
     * 获取网络图片流(附加)
     *
     * @param url
     * @return
     */
    public static InputStream getImageStream(String url) {
        try {
            HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
            connection.setReadTimeout(5000);
            connection.setConnectTimeout(5000);
            connection.setRequestMethod("GET");
            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = connection.getInputStream();
                return inputStream;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

具体使用

其中的file是指上传的MultipartFile

我们将MultipartFile写入了一个临时文件中

对临时文件获取了其exif信息,根据exif信息确定了旋转的

然后对临时文件旋转之后又再次写入临时文件中

        File file2 =  multipartFileToFile(multipartFile); //获取文件流
        BufferedImage originalImg = ImageIO.read(multipartFile.getInputStream());
        int imageWidth = originalImg.getWidth();
        int imageHeight = originalImg.getHeight();
        Metadata metadata = JpegMetadataReader.readMetadata(file2);
        Directory directory = metadata.getDirectory(ExifDirectory.class);
        if(directory.containsTag(ExifDirectory.TAG_ORIENTATION)){ // Exif信息中有保存方向,把信息复制到缩略图
            int orientation = 0; // 原图片的方向信息

            orientation = directory.getInt(ExifDirectory.TAG_ORIENTATION);
            if(6 == orientation) {//翻转了90°和270°的,长宽对调      

                imageWidth = originalImg.getHeight();//上传图片的宽
                imageHeight = originalImg.getWidth(); //上传图片的高
                BufferedImage newImage = RotateImageUtil.rotateImage(originalImg,90,imageHeight,imageWidth);
                inputStream = bufferedImageToInputStream(newImage);
            }else if(orientation==0||orientation==1) {  
			    //360;  
			} else if(orientation==3) {  
		        //180;  
			}else if(orientation==8) {  
		        //270;  
			}  
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值