You need to enable JavaScript to run this app.
文档中心
veImageX

veImageX

复制全文
下载 pdf
图像处理最佳实践
管理图片 Exif 信息最佳实践
复制全文
下载 pdf
管理图片 Exif 信息最佳实践

以下为您介绍如何使用 HEIF 编码库来实现常见 Exif 处理,包括获取 Exif 信息、获取 Exif 中旋转信息、新增/更新指定 Tag、删除指定 Tag、在编码过程中写入 Exif 信息。

背景介绍

Exif(Exchangeable Image File Format)是用于存储数码照片中的元数据的标准格式。Exif 数据通常嵌入在图像文件中,包含了关于图像及其创建过程的各种信息,如基本图像信息、相机信息、GPS 信息等。

在 Exif 中,Tag 是用于标识和存储特定元数据信息的单元。Exif 数据是由多个不同的 Tag 组成的,每个 Tag 都有特定的编号、名称和数据格式,用于存储某一方面的信息。例如,有一个 Tag 用于存储照片的拍摄时间,另一个 Tag 用于存储相机的光圈值等。

当需要读取或修改 Exif 数据时,实际上是对其中的各个 Tag 进行操作。例如,在编程中,如果要获取一张照片的拍摄时间,就需要找到对应的表示拍摄时间的 Exif Tag,然后按照其数据格式读取其中的数据。

应用场景

veImageX 提供了多个 Exif 相关接口,支持多种处理能力。以下是两个典型应用场景:

  1. 保持图像方向一致:例如,在将 jpeg 原图编码为 HEIC 的过程中,可以通过提取 Exif 信息中的旋转信息,确保生成的 Heic 编码产物与原图方向保持一致,避免出现图像显示角度异常的情况,提升用户查看图像的体验。

  2. 保护用户隐私:例如,当上传照片时,可删除与隐私相关的 Exif 数据,例如 GPS 位置信息、相机的唯一标识符等。在节省网络带宽的同时,还能保护用户的隐私安全。

注意事项

  • 支持的原图格式有 JPEG、PNG、WEBP、HEIC。
  • 不支持对原图写入 Exif 信息。

前提条件

准备操作

配置白名单

HEIF 编码库为白名单能力,使用前请提交工单联系技术支持配置白名单。

获取配置信息

您需要在集成 HEIF 编码库前,在 veImageX 获取以下配置信息。

  1. 获取 APPID:在 veImageX 控制台 的应用管理页面,创建 APP 类型应用后。在应用卡片中查看 AppID 。

  2. 获取 Token:在上面应用卡片中,单击 查看 Token,获取账号唯一的 Token 值。

  3. 购买授权:在上面应用卡片中的 License 授权区域,单击 购买授权 按钮。在购买弹窗中,SDK 类型选择客户端 HEIF 库,版本类型选择 HEIF 编码。调试期间,建议您购买一个月有效期的免费试用版授权。购买完成后,获取授权码。

集成 HEIF 编码库

类型Android 端iOS 端
集成文档集成 HEIF 编码库-Android集成 HEIF 编码库-iOS

集成流程

  1. 添加 Maven 仓库

  2. 获取 SDK 版本号。

说明

请使用 3.2.1-tob 及之后版本。

  1. 添加 SDK 依赖。

说明

请务必添加 authorization 、nativeheifencoder 和 nativelibexif 依赖。

  1. 配置混淆规则
  2. 配置授权

说明

填入获取的 AppID、Token、授权码。

  1. 编码准备
  1. 获取 SDK 版本号。

说明

请使用 1.44.1.6-premium 及之后版本

  1. 接入编码库。

说明

请务必接入 ImageHeifEncoder 和 ImageExifEditor。

  1. 配置授权

说明

填入获取的 AppID、Token、授权码。

具体使用

接入 HEIF 编码库后,您可按照以下内容实现对图片 Exif 信息的获取、新增、更新、删除,以及在编码过程中写入 Exif 信息,使编码后 HEIC 图携带指定的 Exif 信息。

传入图片

在手机中传入一张测试图片。例如,可以使用 adb 命令将 PC 端图片导入到手机中。

adb push /Users/xxxxx/Desktop/ExifPics/exif.png /storage/emulated/0/ExifPic/exif.png
	

获取图片的 Exif 信息

支持提取 WebP、JPEG、PNG、HEIC 格式图片内的 Exif 信息,并以 Map 的形式展示,key 为具体 Tag 名称,Value 为 Tag 的内容。具体代码示例如下所示:

  • 获取图片中的全部 Exif 信息

说明

因为提取 Exif 信息操作涉及到 IO 操作,往往较为耗时,因此建议在子线程中调用该方法。

具体接口描述请参考集成 HEIF 编码库-Android

thread {
    val inputFilePath = "/storage/emulated/0/ExifPic/exif.png" //指定要获取 Exif 信息的图片文件在 Android 设备存储中的路径
    val exifHelper = BDExifHelper(inputFilePath)
    // 获取经过解析的 exif 的 map 信息
    exifHelper.exifTagMap?.let {
        runOnUiThread {
            mTvExifInfo1.text = it.toString()
        }
    }
}
	

示例:获取的 Exif 信息如下所示。

{YResoution=72,ExifVersion=Exif Version 2.1,FlashpixVersion=FlashPix Version 1.0,XResolution=72,ColorSpace=sRGB,PixelXDimension=3264,PixelYDimension=2448,Orientation=Right-top,Resolution=lnch}
  • 获取 Exif 中的旋转信息

具体接口描述请参考集成 HEIF 编码库-Android

thread {
    val inputFilePath = "/storage/emulated/0/ExifPic/exif.png" //指定要获取 Exif 旋转信息的图片文件在 Android 设备存储中的路径
    val exifHelper = BDExifHelper(inputFilePath)
    // 获取 Exif 中旋转信息
    val oriInfo = exifHelper.obtainOriInfo()
    runOnUiThread {
        mTvExifInfo2.text =
            "Note == Ori:{val:${oriInfo.value}, rotation:${oriInfo.rotation}, flipInHorizontal:${oriInfo.flipInHorizontal}, flipInVertical:${oriInfo.flipInVertical}}"
    }
}
	

示例:获取的 Exif 旋转信息如下所示。

Note == Ori:{val:6,rotation:270,flipInHorizontal:false,flipinVertical:false}

编辑图片的 Exif 信息

通过指定要编辑的 Tag 以及该 Tag 对应的 IFD、格式等信息,实现新增 Tag 或更新 Tag。您可参考 Exif 标准文档查询指定 Tag 对应信息。

  • 若原图中 Tag 内容为空,则表示新增内容;

  • 若原图中 Tag 内容不为空,则表示更新内容。

具体接口描述请参考集成 HEIF 编码库-Android

//指定 Tag 的内容
val str = "用户评论:xxxxxx"      
val strBytes = str.toByteArray(Charsets.UTF_8)
//设置 Exif 相关配置
this.exifHelper.setExifTag(
    //指定 Tag 名称,具体取值请见 BDExifTags。这里以 UserComment 为例
    BDExifTags.BDEXIF_TAG_USER_COMMENT,  
    //指定 UserComment 对应的 ifd,取值如下所示
    // 0:对应 EXIF_IFD_0th 内的 Tag,如 Xresolution
		// 1:对应 EXIF_IFD_1st 内的 Tag,如 Artist
		// 2:对应 EXIF_IFD_EXIF 内的 Tag,如 UserComment
		// 3:对应 EXIF_IFD_GPS 内的 Tag,如 GPSVersionID
		// 4:对应 EXIF_IFD_INTEROPERABILITY 内的 Tag,如 RelatedImageFileFormat
    2,  
    //指定 Tag 对应的格式,根据官方 Exif 标准可知 UserComment 的 Type为 ASCII 格式   
    BDExifFormats.BDEXIF_FORMAT_ASCII,  
    //传入前面准备好的用户评论字符串字节数组的长度
    strBytes.size,
    //传入实际的用户评论字符串对应的字节数组内容
    strBytes
)
runOnUiThread {
    val oriInfo = this.exifHelper.obtainOriInfo()
    mTvExifInfo.text = "after update:" +
            this.exifEditor!!.exifTagMap.toString() + "Note == Ori:{val:${oriInfo.value}, rotation:${oriInfo.rotation}, flipInHorizontal:${oriInfo.flipInHorizontal}, flipInVertical:${oriInfo.flipInVertical}}"
}
	

示例:

  1. 添加 UserComment 前的 Exif 信息如下所示。
{YResoution=72,ExifVersion=Exif Version 2.1,FlashpixVersion=FlashPix Version 1.0,XResolution=72,ColorSpace=Uncalibrated,ResolutionUnit=lnch}
  1. 添加 UserComment 后的 Exif 信息如下所示。
{Resoution=72,ExifVersion=Exif Version 2.1,FlashpixVersion=FlashPix Version 1.0,XResolution=72,UserComment=用户评论:xxxxxx,ColorSpace=Uncalibrated,ResolutionUnit=lnch}

删除图片的 Exif 信息

通过指定 Tag 名称删除图片中的 Exif 信息。您可在获取解析后图片的 Exif 信息后,选择要删除的 Tag。解析后 Exif 内容为 Map 类型,key 为具体 Tag 名称,Value 为 Tag 的内容。

说明

在 Exif 的众多 Tag 中,YResolution、ExifVersion、FlashpixVersion、XResolution、ColorSpace、ResolutionUni 被称为 Base Exif Tag。

  • 如果删除时指定了 Base Exif Tag,那么 Tag 对应的值将恢复为默认值。

  • 如果删除时指定了非 Base Exif Tag,那么 Tag 则会被删除。

具体接口描述请参考集成 HEIF 编码库-Android

thread {
    val inputFilePath = "/storage/emulated/0/ExifPic/exif.png"
    val exifHelper = BDExifHelper(inputFilePath)
    val deleteTags: Array<String>? = arrayOf("Orientation", "xxx", ...)
    exifHelper.deleteExifTag(deleteTags)
}
	

示例:

  1. 删除前的 Exif 信息如下所示。
{YResoution=72,ExifVersion=Exif Version 2.1,FlashpixVersion=FlashPix Version 1.0,XResolution=72,ColorSpace=sRGB,PixelXDimension=3264,PixelYDimension=2448,Orientation=Right-top,Resolution=lnch}
  1. 删除后的 Exif 信息如下所示。
after delete:{YResoution=72,ExifVersion=Exif Version 2.1,FlashpixVersion=FlashPix Version 1.0,XResolution=72,ColorSpace=Uncalibrated,ResolutionUnit=lnch}Note == Ori:{Val:0,rotation:0,flipInHorizontal:false,flipinVertical:false}

编码为携带 Exif 信息的 Heic 图片

您需要在获取图片 Exif 信息后,参考以下内容在原始图片编码为 Heic 的过程中,写入您指定的 Exif 数据,从而获取带有指定 Exif 数据的 HEIC 图。

例如,可以将 jpeg 原图编码为 Heic 的过程中,可以通过提取 Exif 信息中的旋转信息,并在编码过程写入使生成的 Heic 产物与原 jpeg 的方向保持一致。

具体接口描述请参考集成 HEIF 编码库-Android

val  inputFilePath = getInputFilePath()

val  exifHelper = BDExifHelper(inputFilePath)

val  outputStream : FileOutputStream = FileOutputStream(
        getOutFilePath(
                withCreate =  true,
                index = infoBean?.index
        )
)

var  heifEncodeConfig: HeifEncodeConfig = HeifEncodeConfig(inputFilePath, outputStream)

heifEncodeConfig.setExifData(exifHelper.exifData)

HeifEncoder.encode(heifEncodeConfig)  //编码后的 Heic 图片会保存在 outputStream 中,并持有对应 Exif 数据
	

常见问题

如何获取一个 Tag 的 IFD、Format 等信息?

  1. 在已知需要管理的 Tag 名称后,例如 Tag 为 Orientation,那么您可参考 Exif 标准文档查询到 Orientation 是属于 0th IFD。
    alt
  2. 根据 Tag 的名称查询 Orientation 的 Type,Type 为 SHORT。
    alt
最近更新时间:2024.11.22 14:30:11
这个页面对您有帮助吗?
有用
有用
无用
无用