Image Kit提供图片Exif信息的读取与编辑能力。
Exif(Exchangeable image file format)是专门为数码相机的照片设定的文件格式,可以记录数码照片的属性信息和拍摄数据。需要图片包含Exif信息。
在图库、相机、图片编辑等应用中,开发者可以读取图片的拍摄时间、方向、焦距、地理位置等Exif信息,也可以在需要时修改部分Exif信息。例如,当摄像机的手动镜头参数无法自动写入Exif信息,或者因相机断电导致拍摄时间错误时,可手动修正对应的Exif数据。
系统目前仅支持读取和修改部分Exif信息,具体支持范围请参见变量里的OHOS_IMAGE_PROPERTY_XXX类型。不同图片格式对Exif信息的读写支持情况如下。
| 图片格式 | 读取Exif信息 | 修改Exif信息 |
|---|---|---|
| JPG/JPEG | 支持 | 支持 |
| PNG | 支持 | 支持 |
| HEIF | 支持 | 支持 |
| WebP23+ | 支持 | 支持 |
| DNG23+ | 支持 | 不支持 |
Exif信息的读取与编辑相关C API如下,详细介绍请参考image_source_native.h。
| 接口 | 说明 |
|---|---|
| OH_ImageSourceNative_GetImagePropertyWithNull() | 获取指定属性键的Exif信息。 |
| OH_ImageSourceNative_ModifyImageProperty() | 修改指定属性键的Exif信息。 |
在进行应用开发之前,开发者需要打开Native工程的src/main/cpp/CMakeLists.txt,在target_link_libraries依赖中添加libimage_source.so以及日志依赖libhilog_ndk.z.so。
target_link_libraries(entry PUBLIC libhilog_ndk.z.so libimage_source.so)
在DevEco Studio中新建Native C++应用,默认生成的项目中包含index.ets文件,在entry/src/main/cpp目录下会自动生成一个cpp文件(hello.cpp或napi_init.cpp,本示例以hello.cpp文件名为例)。在hello.cpp中实现C API接口调用逻辑,示例代码如下:
读取和编辑图片Exif信息接口使用示例
部分接口从API version 20开始支持,需要开发者在进行开发时选择合适的API版本。
导入相关头文件。
#include <string> #include <hilog/log.h> #include <multimedia/image_framework/image/image_source_native.h> #include "napi/native_api.h"
日志宏定义可参考下述代码按实际需求自行修改。
#undef LOG_DOMAIN #undef LOG_TAG #define LOG_DOMAIN 0x3200 #define LOG_TAG "IMAGE_SAMPLE"
定义ImageSourceNative类。
class ImageSourceNative {
public:
OH_ImageSource_Info *imageInfo;
OH_ImageSourceNative *source = nullptr;
OH_PixelmapNative *resPixMap = nullptr;
OH_Pixelmap_ImageInfo *pixelmapImageInfo = nullptr;
uint32_t frameCnt = 0;
ImageSourceNative() {}
~ImageSourceNative() {}
}; 创建ImageSourceNative的一个实例。
static ImageSourceNative *g_thisImageSource = new ImageSourceNative();
创建GetJsResult函数处理napi返回值。
// 处理napi返回值。
napi_value GetJsResult(napi_env env, int result)
{
napi_value resultNapi = nullptr;
napi_create_int32(env, result, &resultNapi);
return resultNapi;
} 在成功创建ImageSource对象后,读取、编辑Exif信息。
// 获取指定property的value值。
napi_value GetImageProperty(napi_env env, napi_callback_info info)
{
napi_value argValue[1] = {nullptr};
size_t argCount = 1;
if (napi_get_cb_info(env, info, &argCount, argValue, nullptr, nullptr) != napi_ok || argCount < 1 ||
argValue[0] == nullptr) {
OH_LOG_ERROR(LOG_APP, "GetImageProperty napi_get_cb_info failed!");
return GetJsResult(env, IMAGE_BAD_PARAMETER);
}
// 修改指定属性键的值。
char key[MAX_STRING_LENGTH] = {0};
size_t keySize = 0;
if (napi_get_value_string_utf8(env, argValue[0], key, sizeof(key), &keySize) != napi_ok) {
OH_LOG_ERROR(LOG_APP, "GetImageProperty napi_get_value_string_utf8 failed!");
return GetJsResult(env, IMAGE_BAD_PARAMETER);
}
key[MAX_STRING_LENGTH - 1] = '\0';
Image_String getKey;
getKey.data = key;
getKey.size = keySize;
Image_String getValue = {nullptr, 0};
OH_LOG_INFO(LOG_APP, "OH_ImageSourceNative_GetImageProperty key: %{public}s.", getKey.data);
Image_ErrorCode errCode = OH_ImageSourceNative_GetImagePropertyWithNull(g_thisImageSource->source,
&getKey, &getValue);
if (errCode != IMAGE_SUCCESS) {
OH_LOG_ERROR(LOG_APP, "OH_ImageSourceNative_GetImageProperty failed, errCode: %{public}d.", errCode);
if (getValue.data != nullptr) {
free(getValue.data);
getValue.data = nullptr;
}
return GetJsResult(env, errCode);
}
napi_value resultNapi = nullptr;
napi_create_string_utf8(env, getValue.data, getValue.size, &resultNapi);
free(getValue.data);
getValue.data = nullptr;
return resultNapi;
}
// 修改指定property的value值。
napi_value ModifyImageProperty(napi_env env, napi_callback_info info)
{
napi_value argValue[2] = {nullptr};
size_t argCount = 2;
const size_t minCount = 2;
if (napi_get_cb_info(env, info, &argCount, argValue, nullptr, nullptr) != napi_ok || argCount < minCount ||
argValue[0] == nullptr || argValue[1] == nullptr) {
OH_LOG_ERROR(LOG_APP, "ModifyImageProperty napi_get_cb_info failed!");
return GetJsResult(env, IMAGE_BAD_PARAMETER);
}
// 获取要修改的key值。
char key[MAX_STRING_LENGTH] = {0};
size_t keySize = 0;
if (napi_get_value_string_utf8(env, argValue[0], key, sizeof(key), &keySize) != napi_ok) {
OH_LOG_ERROR(LOG_APP, "ModifyImageProperty key napi_get_value_string_utf8 failed!");
return GetJsResult(env, IMAGE_BAD_PARAMETER);
}
key[MAX_STRING_LENGTH - 1] = '\0';
Image_String setKey;
setKey.data = key;
setKey.size = keySize;
OH_LOG_INFO(LOG_APP, "ModifyImageProperty key: %{public}s.", setKey.data);
// 获取要修改的value值。
char value[MAX_STRING_LENGTH] = {0};
size_t valueSize = 0;
if (napi_get_value_string_utf8(env, argValue[1], value, sizeof(value), &valueSize) != napi_ok) {
OH_LOG_ERROR(LOG_APP, "ModifyImageProperty value napi_get_value_string_utf8 failed!");
return GetJsResult(env, IMAGE_BAD_PARAMETER);
}
value[MAX_STRING_LENGTH - 1] = '\0';
Image_String setValue;
setValue.data = value;
setValue.size = valueSize;
OH_LOG_INFO(LOG_APP, "ModifyImageProperty value: %{public}s.", setValue.data);
Image_ErrorCode errCode = OH_ImageSourceNative_ModifyImageProperty(g_thisImageSource->source, &setKey, &setValue);
return GetJsResult(env, errCode);
}