Java修改图片元数据Exif信息

最近项目里面涉及到了图片的元数据修改,这里把详细的内容给大家分享一下
项目用到了两个Jar包,分别是 mediautil-1.0.jar,metadata-extractor-2.3.1.jar。
重点是mediautil这个jar包,附上它的官方链接:http://mediachest.sourceforge.net/mediautil/,里面有一些它的官方示例,有一点需要注意的是,官网有一个更新补丁,我们需要将补丁包下载解压缩之后放入我们的项目解压后放入项目src下
后续在进行EXIF信息修改的java类中引用刚刚解压好的文件。
下面附上一段完整的修改图片EXif信息代码

package com.test;

import mediautil.gen.Rational;
import mediautil.image.jpeg.Entry;
import mediautil.image.jpeg.Exif;
import mediautil.image.jpeg.IFD;
import mediautil.image.jpeg.LLJTran;

import java.io.*;

/**
 * 重写照片EXIF信息
 *
 * @author gzy
 * 2022.05.20
 */
public class Test {

    public static void main(String[] args) throws Exception {
        main1();
    }

    public static void main1() throws Exception {
        InputStream fip = new FileInputStream("C:\\1.jpg");
        LLJTran llj = new LLJTran(fip);
        llj.read(LLJTran.READ_INFO, true);
        //这里是重点,网上很多人出现 mediautil.image.jpeg.JPEG cannot be cast to mediautil.image.jpeg.Exif 这个错误,原因是这张图片没有Exif头,需要给他初始化一个
        if (!(llj.getImageInfo() instanceof Exif)) {
            llj.addAppx(LLJTran.dummyExifHeader, 0,
                    LLJTran.dummyExifHeader.length, true);
        }
        Exif exif = (Exif) llj.getImageInfo();
        //获取基础标签
        IFD mainIfd = exif.getIFDs()[0];
        //设置相机制造商
        Entry e = new Entry(Exif.ASCII);
        e.setValue(0, "leica");
        mainIfd.addEntry(Exif.MAKE, e);
        //设置相机型号
        e = new Entry(Exif.ASCII);
        e.setValue(0, "leica");
        mainIfd.addEntry(Exif.MODEL, e);
        //设置描述
        e = new Entry(Exif.ASCII);
        e.setValue(0, "xxx");
        mainIfd.addEntry(Exif.IMAGEDESCRIPTION, e);
        //版权
        e = new Entry(Exif.ASCII);
        e.setValue(0, "xxx");
        mainIfd.addEntry(Exif.COPYRIGHT, e);
       	//获取私有标签
        IFD exifOffSetId = mainIfd.getIFD(Exif.EXIFOFFSET);
        if (exifOffSetId == null) {
            exifOffSetId = new IFD(Exif.EXIFOFFSET, Exif.LONG);
            mainIfd.addIFD(exifOffSetId);
        }
        exifOffSetId.setEntry(Exif.DATETIMEORIGINAL, 0, e);
        e = new Entry(Exif.RATIONAL);
        e.setValue(0, new Rational(1, 250));
        exifOffSetId.setEntry(Exif.EXPOSURETIME, 0, e);
        //修改图片光圈值
        e = new Entry(Exif.RATIONAL);
        e.setValue(0, new Rational(16, 14));
        exifOffSetId.setEntry(Exif.APERTUREVALUE, 0, e);
        //修改图片ISO速度
        e = new Entry(Exif.SHORT);
        e.setValue(0, 200);
        exifOffSetId.setEntry(Exif.ISOSPEEDRATINGS, 0, e);
        //修改图片焦距
        e = new Entry(Exif.RATIONAL);
        e.setValue(0, new Rational(50, 1));
        exifOffSetId.setEntry(Exif.FOCALLENGTH, 0, e);
        //修改图片35毫米焦距
        e = new Entry(Exif.SHORT);
        e.setValue(0, 50);
        exifOffSetId.setEntry(Exif.FOCALLENGTHIN35MMFILM, 0, e);
        //修改目标距离
        e = new Entry(Exif.RATIONAL);
        e.setValue(0, new Rational(5, 10));
        exifOffSetId.setEntry(Exif.SUBJECTDISTANCE, 0, e);
        //修改图片闪光能量值
        e = new Entry(Exif.RATIONAL);
        e.setValue(0, new Rational(7800, 1));
        exifOffSetId.setEntry(Exif.FLASHENERGY, 0, e);
        //修改图片亮度
        e = new Entry(Exif.SHORT);
        e.setValue(0, 7);
        exifOffSetId.setEntry(Exif.BRIGHTNESSVALUE, 0, e);
        //修改图片光源
        e = new Entry(Exif.SHORT);
        e.setValue(0, 0);
        exifOffSetId.setEntry(Exif.LIGHTSOURCE, 0, e);
        //修改图片白平衡
        e = new Entry(Exif.SHORT);
        e.setValue(0, 0);
        exifOffSetId.setEntry(Exif.EXPOSUREMODE, 0, e);
        //修改图曝光程序
        e = new Entry(Exif.SHORT);
        e.setValue(0, 2);
        exifOffSetId.setEntry(Exif.EXPOSUREPROGRAM, 0, e);
        //修改图清晰度
        e = new Entry(Exif.SHORT);
        e.setValue(0, 2);
        exifOffSetId.setEntry(Exif.SHARPNESS, 0, e);
        //修改图像饱和度
        e = new Entry(Exif.SHORT);
        e.setValue(0, 0);
        exifOffSetId.setEntry(Exif.SATURATION, 0, e);
        //修改图像对比度
        e = new Entry(Exif.SHORT);
        e.setValue(0, 0);
        exifOffSetId.setEntry(Exif.CONTRAST, 0, e);
        //修改图像Exif版本
        e = new Entry(Exif.ASCII);
        e.setValue(0, "0230");
        exifOffSetId.setEntry(Exif.EXIFVERSION, 0, e);
		//获取GPS标签
        IFD gpsIfd = mainIfd.getIFD(Exif.GPSINFO);
        if (gpsIfd == null) {
            System.out.println("Gps IFD not found adding..");
            gpsIfd = new IFD(Exif.GPSINFO, Exif.LONG);
            mainIfd.addIFD(gpsIfd);
        }

        //修改图片GPS信息
        e = new Entry(Exif.ASCII);
        e.setValue(0, 'N');
        gpsIfd.setEntry(new Integer(Exif.GPSLatitudeRef), 0, e);
        e = new Entry(Exif.RATIONAL);
        e.setValue(0, new Rational(45, 1));
        e.setValue(1, new Rational(39786653, 100000));
        e.setValue(2, new Rational(0, 1));
        gpsIfd.setEntry(new Integer(Exif.GPSLatitude), 0, e);

        e = new Entry(Exif.ASCII);
        e.setValue(0, 'E');
        gpsIfd.setEntry(new Integer(Exif.GPSLongitudeRef), 0, e);
        e = new Entry(Exif.RATIONAL);
        e.setValue(0, new Rational(87, 1));
        e.setValue(1, new Rational(116562968, 100000));
        e.setValue(2, new Rational(0, 1));
        gpsIfd.setEntry(new Integer(Exif.GPSLongitude), 0, e);
        llj.refreshAppx(); // Recreate Marker Data for changes done
        // 改写后的文件
        String fileName = "C:\\test5.jpg";
        OutputStream out = new BufferedOutputStream(new FileOutputStream(fileName));
        llj.xferInfo(null, out, LLJTran.REPLACE, LLJTran.REPLACE);
        fip.close();
        out.close();
        llj.freeMemory();
    }

}

图片相关信息修改的对照表附上链接 https://www.awaresystems.be/imaging/tiff/tifftags/baseline.html
不同的exif信息是存放在不同的exif tag里面的,所以修改的方式不一样,具体的所属标签可以去对照表里面查看,下面是一些比较常用的标签获取代码,具体的一些其他标签可以在上面链接里面查找

//获取基本标签
IFD mainIfd = exif.getIFDs()[0];
//获取Exif私有标签
IFD exifOffSetId = mainIfd.getIFD(Exif.EXIFOFFSET);
//获取GPS标签
IFD gpsIfd = mainIfd.getIFD(Exif.GPSINFO);

在这里插入图片描述
上面是一些基本的属性,它的Hex分别一一对应Exif.java里面的静态变量
比如相机型号Model:下面是Exif.java对应的变量

 /** Identifies the MODEL tag */
 public final static int MODEL = 0x110;

在这里插入图片描述

图片里是相机型号在元数据里的对照信息,Type是它对应编码,下面是基本写法

 //获取基本标签
 IFD mainIfd = exif.getIFDs()[0];
 //设置编码类型
 Entry e = new Entry(Exif.ASCII);
 //设置值
 e.setValue(0, "leica");
 //给标签内容赋值
 mainIfd.addEntry(Exif.MODEL, e);

具体的图片信息修改可以参考下贴出来的完整代码 ,其他的一些Exif读取,缩略图修改大家可以去看看MediaUtil的官方示例

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值