起因
因项目需要,要求在JPG图片中添加自定义属性信息,在网上找了很久,发现大多数是读取ESIF信息,键值信息都是固定死的,不符合需求,后面找到了类库,也没找到关于XMP数据修改写入生成图片的,不过最后在该处获得了灵感并借鉴了部分代码:/questions/23253281/reading-jpg-files-xmp-metadata;实现思路:获取图片中的XMP元数据块,添加自定义属性信息,替换XMP数据,生成新的图片的,大功告成
引用
xmpcore
6.1.10
编写XMP添加组件类
import ;
import ;
import ;
import ;
import .*;
import ;
import ;
import ;
/**
* 图片读取添加XMP数据:
* 实现思路:获取图片中xmpmeta块信息,编辑替换
* @author lijiongquan
*/
public class XMPUtil {
private final byte[] OPEN_ARR = "
private final byte[] CLOSE_ARR = "
".getBytes();private final String namespace = "/xxxx/1.0/";
private final String xmpTag = "xxxx:";
private String orgPath ;
private String destPath;
private Map xmpMap;
/**
* 添加图片XMP数据
* @param orgPath 图片路径
* @param destPath 生成图片路径
* @param xmpMap 添加数据集
*/
public void changeImgXMP(String orgPath, String destPath, Map xmpMap){
= orgPath;
= destPath;
= xmpMap;
try{
setXMP();
}catch (Exception e){
();
}
}
private void setXMP()throws Exception{
File orgFile = new File(orgPath);
File destFile = new File(destPath);
if(()){
();
();
}
FileInputStream in = new FileInputStream(orgFile);
ByteArrayOutputStream out = new ByteArrayOutputStream();
copy(in, out);
byte[] fileData = ();
int openIdx = indexOf(fileData, OPEN_ARR, 0);
if(openIdx>0){
int closeIdx = indexOf(fileData, CLOSE_ARR, openIdx + 1) + CLOSE_ARR.length;
byte[] beforeArr = (fileData,0,openIdx);
byte[] afterArr = (fileData,closeIdx+1,);
byte[] xmpArr = (fileData,openIdx,closeIdx);
XMPMeta xmpMeta = (xmpArr);
().registerNamespace(namespace,xmpTag);
addXMPMeta(xmpMeta);
printXMPMeta(xmpMeta);
ByteArrayOutputStream xmpOut = new ByteArrayOutputStream();
(xmpMeta, xmpOut);
byte[] xmpArrNew = ();
FileOutputStream outputStream = new FileOutputStream(destFile);
wirteByte(outputStream, beforeArr);
wirteByte(outputStream, xmpArrNew);
wirteByte(outputStream, afterArr);
();
}
}
private void wirteByte(OutputStream out, byte[] bytes) throws Exception{
(bytes);
();
}
private void addXMPMeta(XMPMeta xmpMeta) throws Exception{
Iterator iter = ().iterator();
while (()){
String key = ();
String value = (key);
xmpMeta.setProperty(namespace,xmpTag+key,value);
}
}
private void printXMPMeta(XMPMeta xmpMeta) throws Exception{
XMPIteratorImpl xmpIterator = (XMPIteratorImpl)();
while (()){
XMPPropertyInfo obj = (XMPPropertyInfo)();
(()+"--"+()+"--"+());
}
}
private int indexOf(byte[] arr, byte[] sub, int start){
int subIdx = 0;
for(int x = start;x < ;x++) {
if(arr[x] == sub[subIdx]){
if(subIdx == - 1){
return x - subIdx;
}
subIdx++;
} else{
subIdx = 0;
}
}
return -1;
}
private void copy(InputStream in, OutputStream out) throws Exception{
int len = -1;
byte[] buf = new byte[1024];
while((len = (buf)) >= 0)
{
(buf, 0, len);
}
();
();
}
}
调用
Map xmpMap = new HashMap<>();
("testKey","testValue");
("testKey222","testValue22");
XMPUtil xmpUtil = new XMPUtil();
("F://","F://", xmpMap);