图片像素完全没变,为什么修图软件仍然知道作者、版权、关键词和编辑记录?

文章封面

做图片处理功能的时候,最开始的思路很简单:把图片解码出来,处理完再编码存出去。

跑了一段时间发现问题:用户说,我图片里的作者信息、版权信息怎么没了?我只是改了个亮度啊。

这时候才意识到:图片除了像素,还有元数据。元数据存在图片文件里,你重新编码的时候不处理,就丢了。XMP 就是其中一种元数据格式。

一、EXIF 和 XMP 有什么区别

很多人把这两个混为一谈。

类型存什么
EXIF拍摄信息:相机型号、光圈、快门、GPS
XMP编辑信息:作者、版权、关键词、编辑记录

EXIF 主要是相机拍的那张照片自带的信息。XMP 更灵活,你可以自己往里加任意自定义标签,存编辑记录、版权信息、关键词等等。

二、XMP 里能存什么

XMP 不是固定格式,你可以往里加各种自定义标签。

标准标签内容
title图片标题
author作者
copyright版权信息
keywords关键词
description描述
自定义标签你自己定义的任何信息

很多修图软件的编辑记录,就是存在 XMP 里的。你打开图片,它就知道你之前做过哪些编辑。

这段代码解决什么问题: 读取图片的 XMP 元数据。
文件: image/XmpReader.ets
用途: 读取图片元数据
接入位置: 图片加载

import image from '@ohos.multimedia.image';

async readXmpData(buf: ArrayBuffer) {
  const source = image.createImageSource(buf);
  const metadata = await source.getImageMetadata();
  
  const xmpData = await metadata.getTaggedImageInfo(
    image.MetadataType.XMP_METADATA
  );
  
  console.log('作者: ' + xmpData['author']);
  console.log('版权: ' + xmpData['copyright']);
  console.log('关键词: ' + xmpData['keywords']);
}

这里 XMP 是按键值对存的。你读的时候,按标签名读就行。

三、修改 XMP 为什么要重新写回

很多人以为:我读出来改了,图片就自动改了。不对。

XMP 是存在文件里的。你修改完,要重新编码写回文件,修改才生效。

步骤操作
1读取图片
2修改 XMP 标签
3重新编码写回文件

少了最后一步,修改就白做了。

四、不同格式支持不一样

还有个坑:不是所有图片格式都支持 XMP。

格式读 XMP写 XMP
JPEG支持支持
PNG支持支持
GIF支持支持
DNG支持不支持
TIFF支持不支持

API 26 的 Image Kit 支持读取这几种格式的 XMP,但写的话只支持 JPEG、PNG、GIF。DNG 和 TIFF 只能读不能写。

业务流程图

五、自定义 Namespace 为什么要注册

很多人想自己加自定义标签,加进去读不出来。

这是因为 XMP 有个 Namespace 的概念。你用自定义的标签,要先注册对应的 Namespace。不注册,系统不认识你的标签。

很多人踩这个坑:直接 setValue 写自定义标签,结果写进去了读不出来。就是没注册 Namespace。

六、隐私字段为什么不能直接分享

还有个容易踩的坑:XMP 里可能存了隐私信息。

比如 GPS 位置、拍摄时间、设备信息。这些信息你分享图片的时候,如果不处理,就跟着图片一起发出去了。

很多人做图片分享功能的时候,直接把原图发出去了。结果用户的位置信息、设备信息全泄露了。

正确的做法是:分享之前,把隐私字段清掉,或者做脱敏处理。

七、几个容易踩的坑

第一个坑:把 EXIF 和 XMP 混为一谈。两个存的东西不一样。

第二个坑:认为重新编码图片一定会保留元数据。不处理就丢了。

第三个坑:自定义 Namespace 未注册。标签写进去了读不出来。

第四个坑:修改元数据后没有正确写回文件。改了白改。

第五个坑:用户隐私字段未经处理直接分享。位置信息泄露。

运行效果图

这次做图片处理最大的体会是:图片不只是像素,还有元数据。元数据里可能存了作者、版权、关键词、编辑记录,甚至还有隐私信息。处理图片的时候,元数据也要一起处理,不然不是信息丢了,就是隐私漏了。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐