在使用java做数字图像处理的时候,有时候需要保留图像的EXIF属性信息,比如相机型号,GPS位置等。处理图像的时候,一般直接通过ImageIO读取图像每个像素上的RGB色彩信息,但是图像的其他属性信息是没有读取的,这样在处理完图像RGB色彩信息,通过ImageIO重新写入图片或写入新图片都不会保留原图的属性信息。

查阅了大量资料,有通过第三方图像处理库来读取的,也有直接通过解析图像文件编码来读取EXIF区域信息。最后查阅java官方文档,发现其实ImageIO下还包含很多图像处理相关的类库,其中IIOImage是一个图像容器,可以存入和取出图像栅格信息(RenderedImage)和属性信息(IIOMetadata)。操作流程如下:

1、通过ImageIO的getImageReadersByFormatName()方法和createImageInputStream()来获取imagereader迭代器和实例化图像输入流;

// 通过ImageIO和图像输入流设置imageReader
Iterator<ImageReader> iterator = ImageIO.getImageReadersByFormatName("JPG"); // 通过ImageIO获取imageReader迭代器
ImageReader imageReader = iterator.next(); // 通过迭代器实例化ImageReader
ImageInputStream imageInputStream = ImageIO.createImageInputStream(srcImage); // 通过ImageIO实例化图像输入流
imageReader.setInput(imageInputStream, true);

2、通过imagereader读取源图片所有信息,存入IIOImage,再从IIOImage中get到属性信息,存入IIOMetadata;

// 读取源图片EXIF信息,存入IIOMetadata
ImageReadParam imageReadParam = imageReader.getDefaultReadParam();
IIOImage iioImage = imageReader.readAll(0, imageReadParam);
IIOMetadata iioMetadata = iioImage.getMetadata();

3、用和读取源图像同样的方式读取目标图片信息;

// 读取目标图片信息
Iterator<ImageReader> iterator2 = ImageIO.getImageReadersByFormatName("JPG");
ImageReader imageReader2 = iterator2.next();
ImageInputStream imageInputStream2 = ImageIO.createImageInputStream(destImage);
imageReader2.setInput(imageInputStream2, true);

4、将源图片iioMetadata信息存入目标图片的IIOImage;

// 将源图片iioMetadata信息存入目标图片的IIOImage
ImageReadParam imageReadParam2 = imageReader2.getDefaultReadParam();
IIOImage iioImage2 = imageReader2.readAll(0, imageReadParam2);
iioImage2.setMetadata(iioMetadata); 

5、通过图像输出流和imagewriter将iioImage写入目标图片;

// 将iioImage写入目标图片
ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(destImage);Iterator<ImageWriter> iterator3 = ImageIO.getImageWritersByFormatName("JPG");
ImageWriter imageWriter = iterator3.next();
imageWriter.setOutput(imageOutputStream);
imageWriter.write(iioImage2);

6、最后不要忘了关闭流;

//关闭流
imageInputStream.close();
imageOutputStream.close();

完整的测试代码如下:

import java.io.File;
import java.util.Iterator;import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;public class test {public static void main(String[] args) throws Exception{File srcImage = new File("C:/Users/admin/Desktop/test/1.jpg");File destImage = new File("C:/Users/admin/Desktop/test/2.jpg");// 通过ImageIO和图像输入流设置imageReaderIterator<ImageReader> iterator = ImageIO.getImageReadersByFormatName("JPG"); // 通过ImageIO获取imageReader迭代器ImageReader imageReader = iterator.next(); // 通过迭代器实例化ImageReaderImageInputStream imageInputStream = ImageIO.createImageInputStream(srcImage); // 通过ImageIO实例化图像输入流imageReader.setInput(imageInputStream, true);// 读取源图片IIOMetadata信息,存入IIOMetadataImageReadParam imageReadParam = imageReader.getDefaultReadParam();IIOImage iioImage = imageReader.readAll(0, imageReadParam);IIOMetadata iioMetadata = iioImage.getMetadata();// 读取目标图片信息Iterator<ImageReader> iterator2 = ImageIO.getImageReadersByFormatName("JPG");ImageReader imageReader2 = iterator2.next();ImageInputStream imageInputStream2 = ImageIO.createImageInputStream(destImage);imageReader2.setInput(imageInputStream2, true);// 将源图片iioMetadata信息存入目标图片的IIOImageImageReadParam imageReadParam2 = imageReader2.getDefaultReadParam();IIOImage iioImage2 = imageReader2.readAll(0, imageReadParam2);iioImage2.setMetadata(iioMetadata); // 将iioImage写入目标图片ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(destImage);Iterator<ImageWriter> iterator3 = ImageIO.getImageWritersByFormatName("JPG");ImageWriter imageWriter = iterator3.next();imageWriter.setOutput(imageOutputStream);imageWriter.write(iioImage2);//关闭流imageInputStream.close();imageOutputStream.close();}
}

可以看到,两张不同照片,此时有了一样的属性信息。另外,实际情况下,处理图像数据,为了减少IO次数,可以从IIOImage中取出图像栅格数据,转为BufferedImage对象,对image进行处理后再存入IIOImage;

BufferedImage image = (BufferedImage) iioImage.getRenderedImage();
iioImage.setRenderedImage(image);

java图像处理,拷贝图像EXIF信息相关推荐

  1. Java获取照片的Exif信息,并解析GPS

    Java获取照片的Exif信息,并解析GPS 1. 效果图 2. 什么是Exif? 3. 源代码 参考 ❤️ 这篇博客将介绍什么EXIF,以及如何用Java语言读取Exif信息,并转换经纬度为位置信息 ...

  2. windows上安装并使用exiftool修改图像exif信息

      使用exiftool可以对图像的exif信息进行读取.修改.写入等操作.在linux系统上可以直接通过命令行安装,非常方便.但是在windows上,一开始我看了这篇博客,感觉里面写的还挺详细的,就 ...

  3. java 修改exif_照片EXIF信息的读取和改写的JAVA实现

    由于项目需要对照片的EXIF信息进行处理,因此在网上搜索了一番.捣鼓出来了,写下,总结. 需要用到2个jar包,metadata-extractor-2.3.1和mediautil-1.0.这2个ja ...

  4. java图像处理之图像裁剪

    图像裁剪即截取原始图像某一部分生成一幅新的图像,某些app也会要求用户将上传图像进行一定程度裁剪来作为头像.图像裁剪实现起来比较简单,下面介绍两种裁剪方式,矩形裁剪和圆形裁剪. 矩形裁剪,定义图像上某 ...

  5. java图像处理之图像融合

    图像融合,把像素大小相同,拍摄位置相同的照片通过一定方式进行融合.下面介绍几种简单的图像融合方式. 1.通过对应像素均值进行融合.这种融合方式可用于处理亮度变换较大的图片,由于相机测光和成像水平有限, ...

  6. java exif 怎么获取属性_Java如何读取图片EXIF信息

    Java如何读取图片EXIF信息 大家知道Java如何读取图片属性信息吗?下面小编为大家整理了Java读取图片EXIF信息的方法,希望能帮到大家! 首先介绍一下什么是EXIF,EXIF是Exchang ...

  7. java 修改照片exif信息

    参考文章: java更改图片拍摄信息及其他Exif详细信息 Java修改图片元数据Exif信息 Commons Imaging开源网站介绍 引入类 <dependency><grou ...

  8. java exif 语言编码_Java读取图片EXIF信息的代码

    Java读取图片EXIF信息的代码 本文实例讲述了Java读取图片EXIF信息的方法.分享给大家供大家参考.具体分析如下: 首先介绍一下什么是EXIF,EXIF是Exchangeable Image ...

  9. 轻松获取图片和视频文件的Exif信息-Java篇

    前言 随着现在实景地图的如火如荼建设,无人机等航拍测绘手段的不断升级,我们在获取全景照片或者正射影像,全景视频等数据上更加快速.便捷.由于无人机本身不进行相关数据的处理,比如全景地图的生成.视频的信息 ...

最新文章

  1. docker容器虚拟化技术_Docker,虚拟机和容器的全面介绍
  2. ElasticSearch logo 分布式搜索引擎 ElasticSearch
  3. storm的基本概念
  4. oracle 去除重复的信息
  5. tensorboard使用_tensorboard查看训练曲线
  6. mysql my.ini my.cnf_Mysql配置文件my.ini/my.cnf
  7. 推送ActivityFeed到Teams
  8. jQuery常用的层次选择器
  9. 单处理机系统的进程调度动态优先_操作系统复习笔记(王道)C2.1
  10. 服务器显示转速负数,Moldflow使用常见问题及解决方案
  11. mysql 超时_为MySQL设置查询超时
  12. BOMTool更新到1.3.0.10
  13. MATLAB深度学习 2019
  14. 一文理清集成运算放大器 ---- 总结篇
  15. matlab有LLG方程的解么,matlab在常微分方程数值解中应用.docx
  16. leetcode 1276. 不浪费原料的汉堡制作方案(C++)
  17. 编译原理:LL(1)语法分析器的实现(内含代码详细注释)
  18. 2021最新chrome浏览器与chromedriver版本对照表
  19. 解决阿里云服务器提示挖矿程序风险
  20. 机械工程毕业论文题目

热门文章

  1. Leecode22. 括号生成——Leecode大厂热题100道系列
  2. 【详细注释】1058 选择题 (20 分)
  3. [leetcode]151.翻转字符串里的单词
  4. Eclipse基础设置
  5. Markdown语法补充
  6. android activity 被notification启动,Android通知Notification全面剖析
  7. php 千分制显示数字,千分制计算说明
  8. c#sort升序还是降序_c# List的sort排序方法详解
  9. java简单纸牌游戏_2020年最佳2人棋盘游戏:拼凑,Kingdomino等
  10. python2.7安装scrapy_python 2.7 的Scrapy安装介绍