使用Image\_NativeModule完成位图操作
===========================

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

#### 开发步骤

#### \[h2\]添加链接库

在进行应用开发之前，开发者需要打开native工程的src/main/cpp/CMakeLists.txt，在target\_link\_libraries依赖中添加libpixelmap.so以及日志依赖libhilog\_ndk.z.so。

target\_link\_libraries(entry PUBLIC libhilog\_ndk.z.so libpixelmap.so)

#### \[h2\]Native接口调用

具体接口说明请参考[Image\_NativeModule](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-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实例，进行图片像素数据的读写，对图片进行缩放、位置变换、反转、旋转、裁剪等操作。

#include <hilog/log.h>
#include <multimedia/image\_framework/image/pixelmap\_native.h>

#undef LOG\_DOMAIN
#undef LOG\_TAG
#define LOG\_DOMAIN 0x3200
#define LOG\_TAG "MY\_TAG"

Image\_ErrorCode PixelmapTest()
{
    uint8\_t data\[96\];
    size\_t dataSize = 96;
    for (int i = 0; i < dataSize; i++) {
        data\[i\] = i + 1;
    }

    // 创建参数结构体实例，并设置参数。
    OH\_Pixelmap\_InitializationOptions \*createOpts;
    OH\_PixelmapInitializationOptions\_Create(&createOpts);
    OH\_PixelmapInitializationOptions\_SetWidth(createOpts, 6);
    OH\_PixelmapInitializationOptions\_SetHeight(createOpts, 4);
    OH\_PixelmapInitializationOptions\_SetPixelFormat(createOpts, PIXEL\_FORMAT\_RGBA\_8888);
    OH\_PixelmapInitializationOptions\_SetAlphaType(createOpts, PIXELMAP\_ALPHA\_TYPE\_UNKNOWN);

    // 创建Pixelmap实例。
    OH\_PixelmapNative \*pixelmap = nullptr;
    Image\_ErrorCode errCode = OH\_PixelmapNative\_CreatePixelmap(data, dataSize, createOpts, &pixelmap);

    // 读取图像像素数据，结果写入数组里。
    uint8\_t destination\[96\];
    size\_t destinationSize = 96;
    errCode = OH\_PixelmapNative\_ReadPixels(pixelmap, destination, &destinationSize);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "ImagePixelmapNativeCTest pixelmapTest OH\_PixelmapNative\_ReadPixels failed, errCode: %{public}d.", errCode);
        return errCode;
    }

    // 读取缓冲区中的图片数据，结果写入Pixelmap中。
    uint8\_t source\[96\];
    size\_t sourceSize = 96;
    for (int i = 0; i < sourceSize; i++) {
        source\[i\] = i + 1;
    }
    errCode = OH\_PixelmapNative\_WritePixels(pixelmap, source, sourceSize);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "ImagePixelmapNativeCTest pixelmapTest OH\_PixelmapNative\_WritePixels failed, errCode: %{public}d.", errCode);
        return errCode;
    }

    // 创建图片信息实例，并获取图像像素信息。
    OH\_Pixelmap\_ImageInfo \*imageInfo;
    OH\_PixelmapImageInfo\_Create(&imageInfo);
    errCode = OH\_PixelmapNative\_GetImageInfo(pixelmap, imageInfo);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "ImagePixelmapNativeCTest pixelmapTest OH\_PixelmapNative\_GetImageInfo failed, errCode: %{public}d.", errCode);
        return errCode;
    }

    // 获取图片的宽，高，pixel格式，透明度等信息。
    uint32\_t width, height, rowStride;
    int32\_t pixelFormat, alphaType;
    OH\_PixelmapImageInfo\_GetWidth(imageInfo, &width);
    OH\_PixelmapImageInfo\_GetHeight(imageInfo, &height);
    OH\_PixelmapImageInfo\_GetRowStride(imageInfo, &rowStride);
    OH\_PixelmapImageInfo\_GetPixelFormat(imageInfo, &pixelFormat);
    OH\_PixelmapImageInfo\_GetAlphaType(imageInfo, &alphaType);
    OH\_PixelmapImageInfo\_Release(imageInfo);
    OH\_LOG\_INFO(LOG\_APP, "ImagePixelmapNativeCTest pixelmapTest GetImageInfo success, width: %{public}d, height: %{public}d, rowStride: %{public}d, pixelFormat: %{public}d, alphaType: %{public}d.", width, height, rowStride, pixelFormat, alphaType);

    // 设置透明比率来让Pixelmap达到对应的透明效果。
    errCode = OH\_PixelmapNative\_Opacity(pixelmap, 0.5);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "ImagePixelmapNativeCTest pixelmapTest OH\_PixelmapNative\_Opacity failed, errCode: %{public}d.", errCode);
        return errCode;
    }

    // 对图片进行缩放。
    errCode = OH\_PixelmapNative\_Scale(pixelmap, 2.0, 1.0);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "ImagePixelmapNativeCTest pixelmapTest OH\_PixelmapNative\_Scale failed, errCode: %{public}d.", errCode);
        return errCode;
    }

    // 对图片进行位置变换。
    errCode = OH\_PixelmapNative\_Translate(pixelmap, 50.0, 10.0);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "ImagePixelmapNativeCTest pixelmapTest OH\_PixelmapNative\_Translate failed, errCode: %{public}d.", errCode);
        return errCode;
    }

    // 对图片进行旋转。
    errCode = OH\_PixelmapNative\_Rotate(pixelmap, 90.0);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "ImagePixelmapNativeCTest pixelmapTest OH\_PixelmapNative\_Rotate failed, errCode: %{public}d.", errCode);
        return errCode;
    }

    // 对图片进行翻转。
    errCode = OH\_PixelmapNative\_Flip(pixelmap, true, true);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "ImagePixelmapNativeCTest pixelmapTest OH\_PixelmapNative\_Flip failed, errCode: %{public}d.", errCode);
        return errCode;
    }

    // 对图片进行裁剪。
    Image\_Region region;
    region.x = 100;
    region.y = 100;
    region.width = 6;
    region.height = 4;
    errCode = OH\_PixelmapNative\_Crop(pixelmap, &region);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "ImagePixelmapNativeCTest pixelmapTest OH\_PixelmapNative\_Crop failed, errCode: %{public}d.", errCode);
        return errCode;
    }

    // 释放Pixelmap, InitializationOptions实例。
    OH\_PixelmapNative\_Release(pixelmap);
    OH\_PixelmapInitializationOptions\_Release(createOpts);
    return IMAGE\_SUCCESS;
}

// PixelMap预乘/非预乘格式转换示例。
Image\_ErrorCode PixelmapConvertAlphaTypeTest()
{
    uint8\_t data\[96\];
    size\_t dataSize = 96;
    for (int i = 0; i < dataSize; i++) {
        data\[i\] = i + 1;
    }

    // 创建参数结构体实例，并设置参数。
    OH\_Pixelmap\_InitializationOptions \*createOpts;
    OH\_PixelmapInitializationOptions\_Create(&createOpts);
    OH\_PixelmapInitializationOptions\_SetWidth(createOpts, 6);
    OH\_PixelmapInitializationOptions\_SetHeight(createOpts, 4);
    OH\_PixelmapInitializationOptions\_SetSrcPixelFormat(createOpts, PIXEL\_FORMAT\_RGBA\_8888);
    OH\_PixelmapInitializationOptions\_SetPixelFormat(createOpts, PIXEL\_FORMAT\_RGBA\_8888);
    OH\_PixelmapInitializationOptions\_SetAlphaType(createOpts, PIXELMAP\_ALPHA\_TYPE\_UNPREMULTIPLIED);

    // 创建非预乘格式的位图实例。
    OH\_PixelmapNative \*SrcPixelmap = nullptr;
    Image\_ErrorCode errCode = OH\_PixelmapNative\_CreatePixelmap(data, dataSize, createOpts, &SrcPixelmap);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "PixelmapConvertAlphaTypeTest CreateSrcPixelMap failed, errCode: %{public}d.", errCode);
    }

    // 创建预乘格式的位图实例，该DstPixelmap实例将用于保存SrcPixelmap转换AlphaType后的数据。
    OH\_PixelmapNative \*DstPixelmap = nullptr;
    OH\_PixelmapInitializationOptions\_SetAlphaType(createOpts, PIXELMAP\_ALPHA\_TYPE\_PREMULTIPLIED);
    errCode = OH\_PixelmapNative\_CreatePixelmap(data, dataSize, createOpts, &DstPixelmap);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "PixelmapConvertAlphaTypeTest CreateDstPixelMap failed, errCode: %{public}d.", errCode);
    }

    // 转换AlphaType，SrcPixelmap的数据将被转换为预乘格式，并保存到DstPixelmap中。
    errCode = OH\_PixelmapNative\_ConvertAlphaFormat(SrcPixelmap, DstPixelmap, true);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "PixelmapConvertAlphaTypeTest ConvertAlphaFormat failed, errCode: %{public}d.", errCode);
    }

    // 释放Pixelmap，InitializationOptions实例。
    OH\_PixelmapNative\_Release(SrcPixelmap);
    OH\_PixelmapNative\_Release(DstPixelmap);
    OH\_PixelmapInitializationOptions\_Release(createOpts);
    return errCode;
}

**提取图片平均颜色示例**

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

#include <cmath>
#include <hilog/log.h>
#include <multimedia/image\_framework/image/pixelmap\_native.h>
// 颜色结构体。
struct AverageColor {
    uint8\_t r;
    uint8\_t g;
    uint8\_t b;
};

// 提取图片平均颜色。
// 基本思路：
// 1. 将原始PixelMap缩放到较小尺寸（如32像素×32像素），减少像素数量以提高计算效率。
// 2. 读取缩放后的像素数据。
// 3. 遍历所有像素，累加R、G、B通道的值。
// 4. 计算各通道的平均值作为最终颜色。
Image\_ErrorCode ExtractAverageColor(OH\_PixelmapNative\* pixelmap, AverageColor& avgColor)
{
    if (pixelmap == nullptr) {
        OH\_LOG\_ERROR(LOG\_APP, "ExtractAverageColor: pixelmap is nullptr");
        return IMAGE\_BAD\_PARAMETER;
    }

    // 获取原始图片信息，判断是否需要缩放。
    OH\_Pixelmap\_ImageInfo\* imageInfo;
    OH\_PixelmapImageInfo\_Create(&imageInfo);
    Image\_ErrorCode errCode = OH\_PixelmapNative\_GetImageInfo(pixelmap, imageInfo);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "ExtractAverageColor: GetImageInfo failed, errCode: %{public}d", errCode);
        OH\_PixelmapImageInfo\_Release(imageInfo);
        return errCode;
    }

    uint32\_t width, height;
    OH\_PixelmapImageInfo\_GetWidth(imageInfo, &width);
    OH\_PixelmapImageInfo\_GetHeight(imageInfo, &height);
    OH\_PixelmapImageInfo\_Release(imageInfo);

    // 定义缩小后的目标尺寸（32像素×32像素是经验值，平衡性能和准确度）。
    const uint32\_t SAMPLE\_SIZE = 32;

    // 如果图片较大，先进行缩放处理。
    if (width > SAMPLE\_SIZE || height > SAMPLE\_SIZE) {
        // 计算缩放比例。
        double scaleX = (double)SAMPLE\_SIZE / width;
        double scaleY = (double)SAMPLE\_SIZE / height;

        // 对图片进行缩放。
        errCode = OH\_PixelmapNative\_Scale(pixelmap, scaleX, scaleY);
        if (errCode != IMAGE\_SUCCESS) {
            OH\_LOG\_ERROR(LOG\_APP, "ExtractAverageColor: Scale failed, errCode: %{public}d", errCode);
            OH\_PixelmapNative\_Release(pixelmap);
            return errCode;
        }
    } else {
        // 图片较小，直接使用原图。
        pixelmap = pixelmap;
    }

    // 重新获取缩放后的图片信息。
    OH\_PixelmapImageInfo\_Create(&imageInfo);
    errCode = OH\_PixelmapNative\_GetImageInfo(pixelmap, imageInfo);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "ExtractAverageColor: GetImageInfo after scale failed, errCode: %{public}d", errCode);
        OH\_PixelmapImageInfo\_Release(imageInfo);
        return errCode;
    }

    uint32\_t scaledWidth, scaledHeight, rowStride;
    int32\_t pixelFormat, alphaType;
    OH\_PixelmapImageInfo\_GetWidth(imageInfo, &scaledWidth);
    OH\_PixelmapImageInfo\_GetHeight(imageInfo, &scaledHeight);
    OH\_PixelmapImageInfo\_GetRowStride(imageInfo, &rowStride);
    OH\_PixelmapImageInfo\_GetPixelFormat(imageInfo, &pixelFormat);
    OH\_PixelmapImageInfo\_GetAlphaType(imageInfo, &alphaType);
    OH\_PixelmapImageInfo\_Release(imageInfo);
    if (pixelFormat != PIXEL\_FORMAT\_RGBA\_8888) {
        // 此案例中只处理RGBA格式。
        return IMAGE\_BAD\_SOURCE;
    }

    // 读取像素数据。
    size\_t bufferSize = rowStride \* scaledHeight;
    uint8\_t\* pixelData = new uint8\_t\[bufferSize\];
    errCode = OH\_PixelmapNative\_ReadPixels(pixelmap, pixelData, &bufferSize);
    if (errCode != IMAGE\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "ExtractAverageColor: ReadPixels failed, errCode: %{public}d", errCode);
        delete\[\] pixelData;
        return errCode;
    }

    // 根据像素格式确定每像素字节数。
    constexpr int bytesPerPixel = 4; // 默认RGBA\_8888

    // 累加RGB值。
    uint64\_t totalR = 0, totalG = 0, totalB = 0;
    uint32\_t pixelCount = 0;

    for (uint32\_t y = 0; y < scaledHeight; y++) {
        for (uint32\_t x = 0; x < scaledWidth; x++) {
            size\_t offset = y \* rowStride + x \* bytesPerPixel;
            // RGBA\_8888格式：R-G-B-A
            totalR += pixelData\[offset\];
            totalG += pixelData\[offset + 1\];
            totalB += pixelData\[offset + 2\];
            pixelCount++;
        }
    }

    // 释放资源。
    delete\[\] pixelData;
    // 计算平均值。
    if (pixelCount > 0) {
        avgColor.r = (uint8\_t)(totalR / pixelCount);
        avgColor.g = (uint8\_t)(totalG / pixelCount);
        avgColor.b = (uint8\_t)(totalB / pixelCount);
    } else {
        avgColor.r = 0;
        avgColor.g = 0;
        avgColor.b = 0;
    }

    OH\_LOG\_INFO(LOG\_APP,
        "ExtractAverageColor success, avgColor: R=%{public}d, G=%{public}d, B=%{public}d, pixelCount=%{public}d",
        avgColor.r, avgColor.g, avgColor.b, pixelCount);

    return IMAGE\_SUCCESS;
}