文档管理中心
您当前浏览的HarmonyOS 5.0.0(API 12)文档归档不再维护,推荐您使用最新版本。详细请参考文档维护策略变更

使用Image完成图片解码

图片解码指将所支持格式的存档图片解码成统一的PixelMap,以便在应用或系统中进行图片显示或图片处理。当前支持的存档图片格式包括JPEG、PNG、GIF、WebP、BMP、SVG、ICO、DNG、HEIF(不同硬件设备支持情况不同)。

开发步骤

图片解码相关API的详细介绍请参见:图片解码接口文档

添加依赖

在进行应用开发之前,开发者需要打开native工程的src/main/cpp/CMakeLists.txt,在target_link_libraries依赖中添加libace_napi.z.so、libpixelmap_ndk.z.so、libimage_source_ndk.z.so、librawfile.z.so以及日志依赖libhilog_ndk.z.so。

收起
自动换行
深色代码主题
复制
  1. target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so libpixelmap_ndk.z.so libimage_source_ndk.z.so librawfile.z.so)

添加接口映射

打开src/main/cpp/hello.cpp文件,在Init函数中添加getSyncPixelMap函数接口映射,作用是以同步的方式生成PixelMap,具体代码如下:

收起
自动换行
深色代码主题
复制
  1. EXTERN_C_START
  2. static napi_value Init(napi_env env, napi_value exports)
  3. {
  4. napi_property_descriptor desc[] = {
  5. { "getSyncPixelMap", nullptr, getSyncPixelMap, nullptr, nullptr, nullptr, napi_default, nullptr },
  6. };
  7. napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
  8. return exports;
  9. }
  10. EXTERN_C_END

JS侧调用

  1. 打开src\main\cpp\types\libentry\index.d.ts(其中libentry根据工程名生成),导入如下引用文件:

    收起
    自动换行
    深色代码主题
    复制
    1. import { image } from '@kit.ImageKit';
    2. import { resourceManager } from '@kit.LocalizationKit';
    3. // 同步调用,入参为资源管理器和图片资源名称,返回PixelMap
    4. export const getSyncPixelMap: (resMgr: resourceManager.ResourceManager, src: string) => image.PixelMap;
  2. 准备图片资源文件,本示例文件名为example.jpg,导入到src\main\resources\rawfile\ 路径下。

  3. 打开src\main\ets\pages\index.ets,导入"libentry.so(根据工程名生成)",调用Native接口,传入JS的资源对象。示例如下:

    收起
    自动换行
    深色代码主题
    复制
    1. import testNapi from 'libentry.so'
    2. import { image } from '@kit.ImageKit';
    3. @Entry
    4. @Component
    5. struct Index {
    6. @State pixelMap : PixelMap | undefined = undefined;
    7. aboutToAppear() {
    8. // 调用自定义的getSyncPixelMap接口,获取pixelMap
    9. this.pixelMap = testNapi.getSyncPixelMap(getContext(this).resourceManager, "example.jpg")
    10. }
    11. build() {
    12. Row() {
    13. Column() {
    14. Image(this.pixelMap)
    15. .width(100)
    16. .height(100)
    17. }
    18. .width('100%')
    19. }
    20. .height('100%')
    21. }
    22. }

Native接口调用

具体接口说明请参考API文档

在hello.cpp文件中获取JS的资源对象,并转为Native的资源对象,即可调用Native接口,调用方式示例代码如下:

添加引用文件

收起
自动换行
深色代码主题
复制
  1. // 引入图片框架、raw文件、raw文件管理和日志打印头文件
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <multimedia/image_framework/image_source_mdk.h>
  5. #include <multimedia/image_framework/image_pixel_map_mdk.h>
  6. #include <rawfile/raw_file.h>
  7. #include <rawfile/raw_file_manager.h>
  8. #include <hilog/log.h>
  9. static napi_value getSyncPixelMap(napi_env env, napi_callback_info info)
  10. {
  11. size_t argc = 2;
  12. napi_value args[2] = {nullptr};
  13. napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
  14. napi_valuetype srcType;
  15. napi_typeof(env, args[0], &srcType);
  16. // 入参args[0]是资源管理器,用来初始化native层的资源管理器
  17. NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, args[0]);
  18. size_t strSize;
  19. char srcBuf[2048];
  20. // 入参args[1]是文件名称
  21. napi_get_value_string_utf8(env, args[1], srcBuf, sizeof(srcBuf), &strSize);
  22. // 用资源管理器打开Raw文件
  23. RawFile * rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, srcBuf);
  24. if (rawFile != NULL) {
  25. // 获取文件大小,并读取数据
  26. long len = OH_ResourceManager_GetRawFileSize(rawFile);
  27. uint8_t * data = static_cast<uint8_t *>(malloc(len));
  28. int res = OH_ResourceManager_ReadRawFile(rawFile, data, len);
  29. OhosImageSource imageSource_c;
  30. imageSource_c.buffer = data;
  31. imageSource_c.bufferSize = len;
  32. OhosImageSourceOps ops{};
  33. napi_value imageSource;
  34. napi_value pixelMap;
  35. // 用读取到的Raw数据创建ImageSource
  36. int32_t ret = OH_ImageSource_Create(env, &imageSource_c, &ops, &imageSource);
  37. // 初始化native层的ImageSource
  38. ImageSourceNative * imageSourceNative_c = OH_ImageSource_InitNative(env, imageSource);
  39. OhosImageDecodingOps decodingOps{};
  40. // 创建pixelMap
  41. OH_ImageSource_CreatePixelMap(imageSourceNative_c, &decodingOps, &pixelMap);
  42. // 下列方法,为gif等动图格式提供。
  43. // napi_value pixelMapList;
  44. // OH_ImageSource_CreatePixelMapList(imageSourceNative_c, &decodingOps, &pixelMapList);
  45. // OhosImageSourceDelayTimeList list{};
  46. // OH_ImageSource_GetDelayTime(imageSourceNative_c, &list);
  47. // uint32_t count;
  48. // OH_ImageSource_GetFrameCount(imageSourceNative_c, &count);
  49. OhosImageSourceInfo info{};
  50. // 读取图片宽高
  51. OH_ImageSource_GetImageInfo(imageSourceNative_c, 0, &info);
  52. OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[decode]", "imageInfo width:%{public}d , height:%{public}d", info.size.width, info.size.height);
  53. // 读取图片源的ImageWidth配置参数并打印日志
  54. OhosImageSourceProperty target;
  55. char exifKey_c[] = "ImageWidth";
  56. target.size = strlen(exifKey_c);
  57. target.value = exifKey_c;
  58. OhosImageSourceProperty response{};
  59. response.size = 20;
  60. response.value = static_cast<char *>(malloc(20));
  61. OH_ImageSource_GetImageProperty(imageSourceNative_c, &target, &response);
  62. OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[decode]", "ImageProperty width after modify:%{public}s", response.value);
  63. // 处理完毕,释放native层资源
  64. OH_ImageSource_Release(imageSourceNative_c);
  65. OH_ResourceManager_CloseRawFile(rawFile);
  66. return pixelMap;
  67. }
  68. OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);
  69. return nullptr;
  70. }

图片框架支持增量式解码,使用方法如下:

收起
自动换行
深色代码主题
复制
  1. // 引入图片框架、raw文件、raw文件管理和日志打印头文件
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <multimedia/image_framework/image_source_mdk.h>
  5. #include <multimedia/image_framework/image_pixel_map_mdk.h>
  6. #include <rawfile/raw_file.h>
  7. #include <rawfile/raw_file_manager.h>
  8. #include <hilog/log.h>
  9. static napi_value getSyncPixelMap(napi_env env, napi_callback_info info)
  10. {
  11. size_t argc = 2;
  12. napi_value args[2] = {nullptr};
  13. napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
  14. napi_valuetype srcType;
  15. napi_typeof(env, args[0], &srcType);
  16. // 入参args[0]是资源管理器,用来初始化native层的资源管理器
  17. NativeResourceManager * mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, args[0]);
  18. size_t strSize;
  19. char srcBuf[2048];
  20. // 入参args[1]是文件名称
  21. napi_get_value_string_utf8(env, args[1], srcBuf, sizeof(srcBuf), &strSize);
  22. // 用资源管理器打开Raw文件
  23. RawFile * rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, srcBuf);
  24. if (rawFile != NULL) {
  25. // 获取文件大小,若大于2048字节,则增量式解码,否则直接全部解码
  26. long len = OH_ResourceManager_GetRawFileSize(rawFile);
  27. if (len > 2048) {
  28. uint8_t * data = static_cast<uint8_t *>(malloc(len));
  29. // 读取文件全部数据
  30. int res = OH_ResourceManager_ReadRawFile(rawFile, data, len);
  31. uint8_t * holderdata = static_cast<uint8_t *>(malloc(len));
  32. OhosImageSource imageSource_c;
  33. // imageSource_c的buffer分配了空间,但是数据是空的
  34. imageSource_c.buffer = holderdata;
  35. imageSource_c.bufferSize = len;
  36. OhosImageSourceOps ops{};
  37. napi_value imageSource;
  38. // 初始化增量ImageSource
  39. OH_ImageSource_CreateIncremental(env, &imageSource_c, &ops, &imageSource);
  40. // 初始化native层的ImageSource
  41. ImageSourceNative * imageSourceNative_c = OH_ImageSource_InitNative(env, imageSource);
  42. // 以下模拟分片加载场景,分两次加载分片。第一次加载2048字节,第二次加载剩余的数据。
  43. OhosImageSourceUpdateData firstData{};
  44. firstData.buffer = data; // 图片数据
  45. firstData.bufferSize = len; // 图片数据总大小
  46. firstData.isCompleted = false;
  47. firstData.offset = 0; // 第一次重头开始加载
  48. firstData.updateLength = 2048; // 第一次加载了2048字节
  49. OH_ImageSource_UpdateData(imageSourceNative_c, &firstData);
  50. OhosImageSourceUpdateData secondData{};
  51. secondData.buffer = data;
  52. secondData.bufferSize = len;
  53. secondData.isCompleted = true; // 最后一次加载,要标记加载完成
  54. secondData.offset = 2048; // 已经加载过2048字节了,第二次偏移已经加载的量
  55. secondData.updateLength = len - 2048; // 第二次加载剩余的数据
  56. OH_ImageSource_UpdateData(imageSourceNative_c, &secondData);
  57. napi_value pixelMap;
  58. OhosImageDecodingOps decodingOps{};
  59. decodingOps.index = 0;
  60. // 创建pixelMap
  61. OH_ImageSource_CreatePixelMap(imageSourceNative_c, &decodingOps, &pixelMap);
  62. // 处理完毕,释放native层资源
  63. OH_ImageSource_Release(imageSourceNative_c);
  64. OH_ResourceManager_CloseRawFile(rawFile);
  65. return pixelMap;
  66. }
  67. // 读取Raw文件全部数据
  68. uint8_t * data = static_cast<uint8_t *>(malloc(len));
  69. int res = OH_ResourceManager_ReadRawFile(rawFile, data, len);
  70. OhosImageSource imageSource_c;
  71. imageSource_c.buffer = data;
  72. imageSource_c.bufferSize = len;
  73. OhosImageSourceOps ops{};
  74. napi_value imageSource;
  75. napi_value pixelMap;
  76. // 用读取到的Raw数据创建ImageSource
  77. int32_t ret = OH_ImageSource_Create(env, &imageSource_c, &ops, &imageSource);
  78. // 初始化native层的ImageSource
  79. ImageSourceNative * imageSourceNative_c = OH_ImageSource_InitNative(env, imageSource);
  80. OhosImageDecodingOps decodingOps{};
  81. // 创建pixelMap
  82. OH_ImageSource_CreatePixelMap(imageSourceNative_c, &decodingOps, &pixelMap);
  83. // 处理完毕,释放native层资源
  84. OH_ImageSource_Release(imageSourceNative_c);
  85. OH_ResourceManager_CloseRawFile(rawFile);
  86. return pixelMap;
  87. }
  88. OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);
  89. return nullptr;
  90. }
在 指南 中进行搜索
请输入您想要搜索的关键词