文档管理中心

使用Image_NativeModule完成位图操作

创建位图,获取位图的宽、高、pixelFormat、alphaType、rowStride信息、对位图进行操作以及释放位图实例。

开发步骤

添加链接库

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

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

Native接口调用

具体接口说明请参考Image_NativeModule。

在DevEco Studio新建Native C++应用,默认生成的项目中包含index.ets文件,在entry\src\main\cpp目录下会自动生成一个cpp文件(hello.cpp或napi_init.cpp,本示例以hello.cpp文件名为例)。在hello.cpp中实现C API接口调用逻辑,示例代码如下:

位图接口使用示例

在初始化参数后创建Pixelmap实例,进行图片像素数据的读写,对图片进行缩放、位置变换、反转、旋转、裁剪等操作。

收起
自动换行
深色代码主题
复制
  1. #include <hilog/log.h>
  2. #include <multimedia/image_framework/image/pixelmap_native.h>
  3. #undef LOG_DOMAIN
  4. #undef LOG_TAG
  5. #define LOG_DOMAIN 0x3200
  6. #define LOG_TAG "MY_TAG"
  7. const uint8_t DATA_SIZE = 96;
  8. const uint8_t OPTS_WIDTH = 6;
  9. const uint8_t OPTS_HEIGHT = 4;
  10. const float OPACITY_VALUE = 0.5;
  11. const float SCALE_X = 2.0;
  12. const float SCALE_Y = 1.0;
  13. const float TRANSLATE_X = 50.0;
  14. const float TRANSLATE_Y = 10.0;
  15. const float ROTATE_ANGLE = 90.0;
  16. const uint8_t REGION_X = 100;
  17. const uint8_t REGION_Y = 100;
  18. const uint8_t REGION_WIDTH = 6;
  19. const uint8_t REGION_HEIGHT = 4;
  20. static Image_ErrorCode CreatePixelMap(OH_PixelmapNative **pixelmap)
  21. {
  22. uint8_t data[DATA_SIZE];
  23. for (int i = 0; i < DATA_SIZE; i++) {
  24. data[i] = i + 1;
  25. }
  26. // 创建参数结构体实例,并设置参数。
  27. OH_Pixelmap_InitializationOptions *createOpts;
  28. OH_PixelmapInitializationOptions_Create(&createOpts);
  29. OH_PixelmapInitializationOptions_SetWidth(createOpts, OPTS_WIDTH);
  30. OH_PixelmapInitializationOptions_SetHeight(createOpts, OPTS_HEIGHT);
  31. OH_PixelmapInitializationOptions_SetPixelFormat(createOpts, PIXEL_FORMAT_RGBA_8888);
  32. OH_PixelmapInitializationOptions_SetAlphaType(createOpts, PIXELMAP_ALPHA_TYPE_UNKNOWN);
  33. Image_ErrorCode errCode = OH_PixelmapNative_CreatePixelmap(data, DATA_SIZE, createOpts, pixelmap);
  34. // 读取图像像素数据,结果写入数组里。
  35. uint8_t destination[DATA_SIZE];
  36. size_t destinationSize = DATA_SIZE;
  37. errCode = OH_PixelmapNative_ReadPixels(*pixelmap, destination, &destinationSize);
  38. if (errCode != IMAGE_SUCCESS) {
  39. OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_ReadPixels failed, errCode: %{public}d.", errCode);
  40. return errCode;
  41. }
  42. // 读取缓冲区中的图片数据,结果写入Pixelmap中。
  43. uint8_t source[DATA_SIZE];
  44. size_t sourceSize = DATA_SIZE;
  45. for (int i = 0; i < sourceSize; i++) {
  46. source[i] = i + 1;
  47. }
  48. errCode = OH_PixelmapNative_WritePixels(*pixelmap, source, sourceSize);
  49. if (errCode != IMAGE_SUCCESS) {
  50. OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_WritePixels failed, errCode: %{public}d.", errCode);
  51. return errCode;
  52. }
  53. // 创建图片信息实例,并获取图像像素信息。
  54. OH_Pixelmap_ImageInfo *imageInfo;
  55. OH_PixelmapImageInfo_Create(&imageInfo);
  56. errCode = OH_PixelmapNative_GetImageInfo(*pixelmap, imageInfo);
  57. if (errCode != IMAGE_SUCCESS) {
  58. OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_GetImageInfo failed, errCode: %{public}d.", errCode);
  59. return errCode;
  60. }
  61. // 获取图片的宽、高、像素格式、透明度类型等信息。
  62. uint32_t width, height, rowStride;
  63. int32_t pixelFormat, alphaType;
  64. OH_PixelmapImageInfo_GetWidth(imageInfo, &width);
  65. OH_PixelmapImageInfo_GetHeight(imageInfo, &height);
  66. OH_PixelmapImageInfo_GetRowStride(imageInfo, &rowStride);
  67. OH_PixelmapImageInfo_GetPixelFormat(imageInfo, &pixelFormat);
  68. OH_PixelmapImageInfo_GetAlphaType(imageInfo, &alphaType);
  69. OH_PixelmapImageInfo_Release(imageInfo);
  70. OH_LOG_INFO(LOG_APP, "Get image info success, width: %{public}d, height: %{public}d, rowStride: %{public}d, "
  71. "pixelFormat: %{public}d, alphaType: %{public}d.", width, height, rowStride, pixelFormat, alphaType);
  72. // 使用完毕后释放InitializationOptions实例。
  73. OH_PixelmapInitializationOptions_Release(createOpts);
  74. return IMAGE_SUCCESS;
  75. }
  76. static Image_ErrorCode PixelmapTest()
  77. {
  78. // 创建Pixelmap实例。
  79. OH_PixelmapNative *pixelmap = nullptr;
  80. Image_ErrorCode errCode = CreatePixelMap(&pixelmap);
  81. if (errCode != IMAGE_SUCCESS) {
  82. return errCode;
  83. }
  84. // 设置透明比率来让Pixelmap达到对应的透明效果。
  85. errCode = OH_PixelmapNative_Opacity(pixelmap, OPACITY_VALUE);
  86. if (errCode != IMAGE_SUCCESS) {
  87. OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_Opacity failed, errCode: %{public}d.", errCode);
  88. return errCode;
  89. }
  90. // 对图片进行缩放。
  91. errCode = OH_PixelmapNative_Scale(pixelmap, SCALE_X, SCALE_Y);
  92. if (errCode != IMAGE_SUCCESS) {
  93. OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_Scale failed, errCode: %{public}d.", errCode);
  94. return errCode;
  95. }
  96. // 对图片进行位置变换。
  97. errCode = OH_PixelmapNative_Translate(pixelmap, TRANSLATE_X, TRANSLATE_Y);
  98. if (errCode != IMAGE_SUCCESS) {
  99. OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_Translate failed, errCode: %{public}d.", errCode);
  100. return errCode;
  101. }
  102. // 对图片进行旋转。
  103. errCode = OH_PixelmapNative_Rotate(pixelmap, ROTATE_ANGLE);
  104. if (errCode != IMAGE_SUCCESS) {
  105. OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_Rotate failed, errCode: %{public}d.", errCode);
  106. return errCode;
  107. }
  108. // 对图片进行翻转。
  109. errCode = OH_PixelmapNative_Flip(pixelmap, true, true);
  110. if (errCode != IMAGE_SUCCESS) {
  111. OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_Flip failed, errCode: %{public}d.", errCode);
  112. return errCode;
  113. }
  114. // 对图片进行裁剪。
  115. Image_Region region;
  116. region.x = REGION_X;
  117. region.y = REGION_Y;
  118. region.width = REGION_WIDTH;
  119. region.height = REGION_HEIGHT;
  120. errCode = OH_PixelmapNative_Crop(pixelmap, &region);
  121. if (errCode != IMAGE_SUCCESS) {
  122. OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_Crop failed, errCode: %{public}d.", errCode);
  123. return errCode;
  124. }
  125. // 使用完毕后释放Pixelmap实例。
  126. OH_PixelmapNative_Release(pixelmap);
  127. return IMAGE_SUCCESS;
  128. }
  129. // PixelMap预乘/非预乘格式转换示例。
  130. static Image_ErrorCode PixelmapConvertAlphaTypeTest()
  131. {
  132. uint8_t data[DATA_SIZE];
  133. for (int i = 0; i < DATA_SIZE; i++) {
  134. data[i] = i + 1;
  135. }
  136. // 创建参数结构体实例,并设置参数。
  137. OH_Pixelmap_InitializationOptions *createOpts;
  138. OH_PixelmapInitializationOptions_Create(&createOpts);
  139. OH_PixelmapInitializationOptions_SetWidth(createOpts, OPTS_WIDTH);
  140. OH_PixelmapInitializationOptions_SetHeight(createOpts, OPTS_HEIGHT);
  141. OH_PixelmapInitializationOptions_SetSrcPixelFormat(createOpts, PIXEL_FORMAT_RGBA_8888);
  142. OH_PixelmapInitializationOptions_SetPixelFormat(createOpts, PIXEL_FORMAT_RGBA_8888);
  143. OH_PixelmapInitializationOptions_SetAlphaType(createOpts, PIXELMAP_ALPHA_TYPE_UNPREMULTIPLIED);
  144. // 创建非预乘格式的位图实例。
  145. OH_PixelmapNative *srcPixelmap = nullptr;
  146. Image_ErrorCode errCode = OH_PixelmapNative_CreatePixelmap(data, DATA_SIZE, createOpts, &srcPixelmap);
  147. if (errCode != IMAGE_SUCCESS) {
  148. OH_LOG_ERROR(LOG_APP, "Create srcPixelMap failed, errCode: %{public}d.", errCode);
  149. }
  150. // 创建预乘格式的位图实例,该dstPixelmap实例将用于保存srcPixelmap转换AlphaType后的数据。
  151. OH_PixelmapNative *dstPixelmap = nullptr;
  152. OH_PixelmapInitializationOptions_SetAlphaType(createOpts, PIXELMAP_ALPHA_TYPE_PREMULTIPLIED);
  153. errCode = OH_PixelmapNative_CreatePixelmap(data, DATA_SIZE, createOpts, &dstPixelmap);
  154. if (errCode != IMAGE_SUCCESS) {
  155. OH_LOG_ERROR(LOG_APP, "Create dstPixelMap failed, errCode: %{public}d.", errCode);
  156. }
  157. // 转换AlphaType,srcPixelmap的数据将被转换为预乘格式,并保存到dstPixelmap中。
  158. errCode = OH_PixelmapNative_ConvertAlphaFormat(srcPixelmap, dstPixelmap, true);
  159. if (errCode != IMAGE_SUCCESS) {
  160. OH_LOG_ERROR(LOG_APP, "OH_PixelmapNative_ConvertAlphaFormat failed, errCode: %{public}d.", errCode);
  161. }
  162. // 释放Pixelmap、InitializationOptions实例。
  163. OH_PixelmapNative_Release(srcPixelmap);
  164. OH_PixelmapNative_Release(dstPixelmap);
  165. OH_PixelmapInitializationOptions_Release(createOpts);
  166. return errCode;
  167. }

提取图片平均颜色示例

通过将图片缩放到较小尺寸,遍历所有像素计算RGB平均值来获取图片的主色调。

收起
自动换行
深色代码主题
复制
  1. #include <hilog/log.h>
  2. #include <multimedia/image_framework/image/pixelmap_native.h>
  3. // 颜色结构体。
  4. struct AverageColor {
  5. uint8_t r;
  6. uint8_t g;
  7. uint8_t b;
  8. };
  9. // 提取图片平均颜色。
  10. // 基本思路:
  11. // 1. 将原始PixelMap缩放到较小尺寸(如32像素×32像素),减少像素数量以提高计算效率。
  12. // 2. 读取缩放后的像素数据。
  13. // 3. 遍历所有像素,累加R、G、B通道的值。
  14. // 4. 计算各通道的平均值作为最终颜色。
  15. Image_ErrorCode ExtractAverageColor(OH_PixelmapNative* pixelmap, AverageColor& avgColor)
  16. {
  17. if (pixelmap == nullptr) {
  18. OH_LOG_ERROR(LOG_APP, "ExtractAverageColor: pixelmap is nullptr");
  19. return IMAGE_BAD_PARAMETER;
  20. }
  21. // 获取原始图片信息,判断是否需要缩放。
  22. OH_Pixelmap_ImageInfo* imageInfo;
  23. OH_PixelmapImageInfo_Create(&imageInfo);
  24. Image_ErrorCode errCode = OH_PixelmapNative_GetImageInfo(pixelmap, imageInfo);
  25. if (errCode != IMAGE_SUCCESS) {
  26. OH_LOG_ERROR(LOG_APP, "ExtractAverageColor: GetImageInfo failed, errCode: %{public}d", errCode);
  27. OH_PixelmapImageInfo_Release(imageInfo);
  28. return errCode;
  29. }
  30. uint32_t width, height;
  31. OH_PixelmapImageInfo_GetWidth(imageInfo, &width);
  32. OH_PixelmapImageInfo_GetHeight(imageInfo, &height);
  33. OH_PixelmapImageInfo_Release(imageInfo);
  34. // 定义缩小后的目标尺寸(32像素×32像素是经验值,平衡性能和准确度)。
  35. const uint32_t SAMPLE_SIZE = 32;
  36. // 如果图片较大,先进行缩放处理。
  37. if (width > SAMPLE_SIZE || height > SAMPLE_SIZE) {
  38. // 计算缩放比例。
  39. double scaleX = (double)SAMPLE_SIZE / width;
  40. double scaleY = (double)SAMPLE_SIZE / height;
  41. // 对图片进行缩放。
  42. errCode = OH_PixelmapNative_Scale(pixelmap, scaleX, scaleY);
  43. if (errCode != IMAGE_SUCCESS) {
  44. OH_LOG_ERROR(LOG_APP, "ExtractAverageColor: Scale failed, errCode: %{public}d", errCode);
  45. return errCode;
  46. }
  47. }
  48. // 重新获取缩放后的图片信息。
  49. OH_PixelmapImageInfo_Create(&imageInfo);
  50. errCode = OH_PixelmapNative_GetImageInfo(pixelmap, imageInfo);
  51. if (errCode != IMAGE_SUCCESS) {
  52. OH_LOG_ERROR(LOG_APP, "ExtractAverageColor: GetImageInfo after scale failed, errCode: %{public}d", errCode);
  53. OH_PixelmapImageInfo_Release(imageInfo);
  54. return errCode;
  55. }
  56. uint32_t scaledWidth, scaledHeight, rowStride;
  57. int32_t pixelFormat, alphaType;
  58. OH_PixelmapImageInfo_GetWidth(imageInfo, &scaledWidth);
  59. OH_PixelmapImageInfo_GetHeight(imageInfo, &scaledHeight);
  60. OH_PixelmapImageInfo_GetRowStride(imageInfo, &rowStride);
  61. OH_PixelmapImageInfo_GetPixelFormat(imageInfo, &pixelFormat);
  62. OH_PixelmapImageInfo_GetAlphaType(imageInfo, &alphaType);
  63. OH_PixelmapImageInfo_Release(imageInfo);
  64. if (pixelFormat != PIXEL_FORMAT_RGBA_8888) {
  65. // 此案例中只处理RGBA格式。
  66. return IMAGE_BAD_SOURCE;
  67. }
  68. // 读取像素数据。
  69. size_t bufferSize = rowStride * scaledHeight;
  70. uint8_t* pixelData = new uint8_t[bufferSize];
  71. errCode = OH_PixelmapNative_ReadPixels(pixelmap, pixelData, &bufferSize);
  72. if (errCode != IMAGE_SUCCESS) {
  73. OH_LOG_ERROR(LOG_APP, "ExtractAverageColor: ReadPixels failed, errCode: %{public}d", errCode);
  74. delete[] pixelData;
  75. return errCode;
  76. }
  77. // 根据像素格式确定每像素字节数。
  78. constexpr int bytesPerPixel = 4; // 默认RGBA_8888
  79. // 累加RGB值。
  80. uint64_t totalR = 0, totalG = 0, totalB = 0;
  81. uint32_t pixelCount = 0;
  82. for (uint32_t y = 0; y < scaledHeight; y++) {
  83. for (uint32_t x = 0; x < scaledWidth; x++) {
  84. size_t offset = y * rowStride + x * bytesPerPixel;
  85. // RGBA_8888格式:R-G-B-A
  86. totalR += pixelData[offset];
  87. totalG += pixelData[offset + 1];
  88. totalB += pixelData[offset + 2];
  89. pixelCount++;
  90. }
  91. }
  92. // 释放资源。
  93. delete[] pixelData;
  94. // 计算平均值。
  95. if (pixelCount > 0) {
  96. avgColor.r = (uint8_t)(totalR / pixelCount);
  97. avgColor.g = (uint8_t)(totalG / pixelCount);
  98. avgColor.b = (uint8_t)(totalB / pixelCount);
  99. } else {
  100. avgColor.r = 0;
  101. avgColor.g = 0;
  102. avgColor.b = 0;
  103. }
  104. OH_LOG_INFO(LOG_APP,
  105. "ExtractAverageColor success, avgColor: R=%{public}d, G=%{public}d, B=%{public}d, pixelCount=%{public}d",
  106. avgColor.r, avgColor.g, avgColor.b, pixelCount);
  107. return IMAGE_SUCCESS;
  108. }