java图像处理,拷贝图像EXIF信息
? ? ? ? 在使用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信息的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java图像处理之拉普拉斯锐化和一阶微分
- 下一篇: java图像处理之自动对比度