鸿蒙(API 12 Beta3版)【使用ImageEffect编辑图片】图片开发指导

场景介绍

ImageEffect提供了一系列接口用于图像的编辑。开发者可以通过ImageEffect接口处理不同图像输入类型Pixelmap、NativeWindow、NativeBuffer或Uri,获得滤镜处理效果。

针对ImageEffect,常见的开发场景如下:

  • 通过ImageEffect提供的Native API接口添加滤镜或滤镜链,设置输入图像,最终生效滤镜效果。
  • 通过注册自定义滤镜,实现开发者的定制化滤镜效果。
  • 通过EffectFilter提供的Native API接口快速实现单个滤镜的处理效果。

接口说明

开发步骤

添加动态链接库

CMakeLists.txt中添加以下lib。

复制代码
target_link_libraries(entry PUBLIC
    libace_ndk.z.so
    libimage_effect.so
    libpixelmap.so
    libnative_window.so
    libnative_buffer.so
)

根据处理的图像类型添加对应动态链接库:Pixelmap(libpixelmap.so)、NativeWindow(libnative_window.so)、NativeBuffer(libnative_buffer.so)

添加头文件

复制代码
#include <multimedia/image_effect/image_effect.h>
#include <multimedia/image_effect/image_effect_filter.h>
#include <multimedia/image_effect/image_effect_errors.h>

通过ImageEffect提供的接口生效图像效果

  1. 创建ImageEffect实例。

    // 创建imageEffect实例,"ImageEdit"是imageEffect实例别名。
    OH_ImageEffect *imageEffect = OH_ImageEffect_Create("ImageEdit");

  2. 添加EffectFilter滤镜。

    // 添加滤镜,获取 OH_EffectFilter 实例。多次调用该接口可以添加多个滤镜,组成滤镜链。
    OH_EffectFilter *filter = OH_ImageEffect_AddFilter(imageEffect, OH_EFFECT_BRIGHTNESS_FILTER);
    CHECK_AND_RETURN_LOG(filter != nullptr, "OH_ImageEffect_AddFilter fail!");

    // 设置滤镜参数, 例如:滤镜强度设置为50。
    ImageEffect_Any value = { .dataType = ImageEffect_DataType::EFFECT_DATA_TYPE_FLOAT, .dataValue.floatValue = 50.f };
    ImageEffect_ErrorCode errorCode = OH_EffectFilter_SetValue(filter, OH_EFFECT_FILTER_INTENSITY_KEY, &value);

  3. 设置处理数据。

场景一:设置 OH_PixelmapNative 输入类型。

OH_PixelmapNative的具体使用方法请参考[Pixelmap开发指导]。

复制代码
// 设置输入的Pixelmap。
errorCode = OH_ImageEffect_SetInputPixelmap(imageEffect, inputPixelmap);
CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_SetInputPixelmap fail!");

// 设置输出的Pixelmap(可选),不调用该接口时会在输入Pixelmap上直接生效滤镜效果。
errorCode = OH_ImageEffect_SetOutputPixelmap(imageEffect, outputPixelmap);
CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_SetOutputPixelmap fail!");

场景二:设置 OH_NativeBuffer 输入类型。

OH_NativeBuffer的具体使用方法请参考[NativeBuffer开发指导]。

复制代码
// 设置输入的NativeBuffer。
errorCode = OH_ImageEffect_SetInputNativeBuffer(imageEffect, inputNativeBuffer);
CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_SetInputNativeBuffer fail!");

// 设置输出的NativeBuffer(可选),不调用该接口时会在输入NativeBuffer上直接生效滤镜效果。
errorCode = OH_ImageEffect_SetOutputNativeBuffer(imageEffect, outputNativeBuffer);
CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_SetOutputNativeBuffer fail!");

场景三:设置 URI 输入类型。

复制代码
// 设置输入的URI。
errorCode = OH_ImageEffect_SetInputUri(imageEffect, inputUri);
CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_SetInputUri fail!");

// 设置输出的URI(可选),不调用该接口时会在输入URI上直接生效滤镜效果。
errorCode = OH_ImageEffect_SetOutputUri(imageEffect, outputUri);
CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_SetOutputUri fail!");

场景四:设置 OHNativeWindow 输入类型。

以相机预览场景为例来说明OHNativeWindow输入场景。XComponent组件为相机预览流提供的SurfaceId,可在native c++层将SurfaceId转换成OHNativeWindow,下面提供一份代码示例。

XComponent模块的具体使用方法请参考[XComponent组件参考]

NativeWindow模块的具体使用方法请参考[OHNativeWindow]

Camera的具体使用方法请参考[Camera预览参考]

(1) 在xxx.ets中添加一个XComponent组件。

复制代码
XComponent({ 
    id: 'xcomponentId', 
    type: 'surface',
    controller: this.mXComponentController, 
    libraryname: 'entry'
})
.onLoad(() => {
    // 获取XComponent的SurfaceId。
    this.mSurfaceId = this.mXComponentController.getXComponentSurfaceId()

    // 调用native接口获取输入SurfaceId。
    this.mSurfaceId = imageEffect.getSurfaceId(this.mSurfaceId)

    // 调用相机接口启动预览,将获取到的输入SurfaceId传递给相机框架
    // ...
})
.width('100%')
.height('100%')

(2) imageEffect.getSurfaceId的native c++层具体实现。

复制代码
// 根据SurfaceId创建NativeWindow,注意创建出来的NativeWindow在使用结束后需要主动调用OH_NativeWindow_DestoryNativeWindow进行释放。
uint64_t outputSurfaceId;
std::istrstream iss(outputSurfaceIdStr);
issue >> outputSurfaceId;
OHNativeWindow *outputNativeWindow = nullptr;
int32_t res = OH_NativeWindow_CreateNativeWindowFromSurfaceId(outputSurfaceId, &outputNativeWindow);
CHECK_AND_RETURN_LOG(res == 0, "OH_NativeWindow_CreateNativeWindowFromSurfaceId fail!");

// 设置输出显示的Surface。
ImageEffect_ErrorCode errorCode = OH_ImageEffect_SetOutputSurface(imageEffect, outputNativeWindow);
CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_SetOutputSurface fail!");

// 获取输入的Surface。注意获取的inputNativeWindow在使用结束后需要主动调用OH_NativeWindow_DestoryNativeWindow进行释放。
OHNativeWindow *inputNativeWindow = nullptr;
errorCode = OH_ImageEffect_GetInputSurface(imageEffect, &inputNativeWindow);
CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_GetInputSurface fail!");

// 从获取到输入的NativeWindow中获取SurfaceId。
uint64_t inputSurfaceId = 0;
res = OH_NativeWindow_GetSurfaceId(inputNativeWindow, &inputSurfaceId);
CHECK_AND_RETURN_LOG(res == 0, "OH_NativeWindow_GetSurfaceId fail!");

// 将SurfaceId转成字符串进行返回。
std::string inputSurfaceIdStr = std::to_string(inputSurfaceId);
  1. 启动效果器。

    // 执行生效滤镜效果。
    errorCode = OH_ImageEffect_Start(imageEffect);
    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_Start fail!");

  2. 停止生效效果(可选,仅在输入Surface场景下才有效)。

    // 停止生效滤镜效果。
    errorCode = OH_ImageEffect_Stop(imageEffect);
    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_Stop fail!");

  3. 序列化效果器(可选)。

    char *info = nullptr;
    errorCode = OH_ImageEffect_Save(imageEffect, &info);
    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_Save fail!");

  4. 销毁效果器实例。

    // 释放imageEffect实例资源。
    errorCode = OH_ImageEffect_Release(imageEffect);
    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result, "OH_ImageEffect_Release fail!");

自定义滤镜

以下步骤描述了如何实现并注册自定义滤镜接口:

  1. 定义 ImageEffect_FilterDelegate。

    // 图像信息结构体。
    struct EffectBufferInfo {
    void *addr = nullptr;
    int32_t width = 0;
    int32_t height = 0;
    int32_t rowSize = 0;
    ImageEffect_Format format = ImageEffect_Format::EFFECT_PIXEL_FORMAT_UNKNOWN;
    };

    // 自定义滤镜具体实现。
    ImageEffect_FilterDelegate filterDelegate = {
    .setValue = [](OH_EffectFilter *filter, const char *key, const ImageEffect_Any *value) {
    // 参数校验,校验成功时返回true,否则返回false。
    // ...
    return true;
    },
    .render = [](OH_EffectFilter *filter, OH_EffectBufferInfo *info, OH_EffectFilterDelegate_PushData pushData) {
    return Render(filter, info, pushData);
    },
    .save = [](OH_EffectFilter *filter, char **info) {
    // 获取自定义所设置的滤镜参数,其中"Brightness"为自定义滤镜的Key,由开发者自己任意指定。
    ImageEffect_Any value;
    ImageEffect_ErrorCode errorCode = OH_EffectFilter_GetValue(filter, "Brightness", &value);
    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, false, "OH_EffectFilter_GetValue fail!");

    复制代码
         // 生成键值对信息。
         json values;
         values["Brightness"] = value.dataValue.floatValue;         
         json root;
         root["name"] = "CustomBrightness";
         root["values"] = values;
     
        // 将json对象转成字符串infoStr
         // ...
    
         // 对*info赋值序列化字符串地址。
         *info = infoStr;
         return true;
     },
     .restore = [](const char *info) {
         // 创建 OH_EffectFilter 实例,其中"CustomBrightness"为自定义滤镜的滤镜名。
         OH_EffectFilter *filter = OH_EffectFilter_Create("CustomBrightness");
         // 解析json字符串info获取key和value。
         // ...
     
         // 设置滤镜参数, value为info中按json解析出来的参数。
         ImageEffect_ErrorCode errorCode = OH_EffectFilter_SetValue(filter, "Brightness", &value);
         
         // ...
         return filter;
     }

    };

其中Render接口的实现分两种场景。

场景一:自定义算法可以直接修改info中的像素数据(比如:亮度调节滤镜)。

复制代码
bool Render(OH_EffectFilter *filter, OH_EffectBufferInfo *info, OH_EffectFilterDelegate_PushData pushData)
{
    // 获取图像信息具体参数。
    EffectBufferInfo inputBufferInfo;
    OH_EffectBufferInfo_GetAddr(info, &inputBufferInfo.addr);
    OH_EffectBufferInfo_GetWidth(info, &inputBufferInfo.width);
    OH_EffectBufferInfo_GetHeight(info, &inputBufferInfo.height);
    OH_EffectBufferInfo_GetRowSize(info, &inputBufferInfo.rowSize);
    OH_EffectBufferInfo_GetEffectFormat(info, &inputBufferInfo.format);

    // 调用自定义滤镜算法。
    ApplyCustomAlgo(inputBufferInfo);

    // 编辑完成后调用pushData直接传递原图。
    pushData(filter, info);
    return true;
}

场景二:自定义算法不能直接修改info中的像素数据(比如:裁剪滤镜)。

复制代码
bool Render(OH_EffectFilter *filter, OH_EffectBufferInfo *info, OH_EffectFilterDelegate_PushData pushData)
{
    // 获取图像信息具体参数。
    EffectBufferInfo inputBufferInfo;
    OH_EffectBufferInfo_GetAddr(info, &inputBufferInfo.addr);
    OH_EffectBufferInfo_GetWidth(info, &inputBufferInfo.width);
    OH_EffectBufferInfo_GetHeight(info, &inputBufferInfo.height);
    OH_EffectBufferInfo_GetRowSize(info, &inputBufferInfo.rowSize);
    OH_EffectBufferInfo_GetEffectFormat(info, &inputBufferInfo.format);

    // 创建输出像素信息。
    EffectBufferInfo outputBufferInfo = CreateOutputBufferInfo(inputBufferInfo);

    // 调用自定义滤镜算法。
    ApplyCustomAlgo(inputBufferInfo, outputBufferInfo);

    // 生成outputOhInfo。
    OH_EffectBufferInfo *outputOhInfo = OH_EffectBufferInfo_Create();
    OH_EffectBufferInfo_SetAddr(outputOhInfo, outputBufferInfo.addr);
    OH_EffectBufferInfo_SetWidth(outputOhInfo, outputBufferInfo.width);
    OH_EffectBufferInfo_SetHeight(outputOhInfo, outputBufferInfo.height);
    OH_EffectBufferInfo_SetRowSize(outputOhInfo, outputBufferInfo.rowSize);
    OH_EffectBufferInfo_SetEffectFormat(outputOhInfo, outputBufferInfo.format);

    // 编辑完成后调用pushData传递outputOhInfo。
    pushData(filter, outputOhInfo);

    // 释放资源。
    OH_EffectBufferInfo_Release(outputOhInfo);
    ReleaseOutputBuffer(outputBufferInfo.addr);

    return true;
}
  1. 生成自定义滤镜信息。

    // 创建 OH_EffectFilterInfo 实例。
    OH_EffectFilterInfo *customFilterInfo = OH_EffectFilterInfo_Create();
    CHECK_AND_RETURN_LOG(customFilterInfo != nullptr, "OH_EffectFilter_GetValue fail!");

    // 设置自定义滤镜滤镜名。
    OH_EffectFilterInfo_SetFilterName(customFilterInfo, "CustomBrightness");

    // 设置自定义滤镜所支持的内存类型。
    ImageEffect_BufferType bufferTypeArray[] = { ImageEffect_BufferType::EFFECT_BUFFER_TYPE_PIXEL };
    OH_EffectFilterInfo_SetSupportedBufferTypes(customFilterInfo, sizeof(bufferTypeArray) / sizeof(ImageEffect_BufferType), bufferTypeArray);

    // 设置自定义滤镜所支持的像素格式。
    ImageEffect_Format formatArray[] = { ImageEffect_Format::EFFECT_PIXEL_FORMAT_RGBA8888 };
    OH_EffectFilterInfo_SetSupportedFormats(customFilterInfo, sizeof(formatArray) / sizeof(ImageEffect_Format), formatArray);

  2. 将 ImageEffect_FilterDelegate 注册到效果器。

    // 注册自定义滤镜。
    ImageEffect_ErrorCode errorCode = OH_EffectFilter_Register(customFilterInfo, &filterDelegate);
    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_EffectFilter_Register fail!");

EffectFilter快速实现单个滤镜的处理效果

  1. 创建滤镜。

    // 创建滤镜。比如:创建对比度效果器。
    OH_EffectFilter *filter = OH_EffectFilter_Create(OH_EFFECT_CONTRAST_FILTER);

  2. 设置滤镜参数。

    // 设置滤镜参数, 滤镜强度设置为50。
    ImageEffect_Any value = {.dataType = ImageEffect_DataType::EFFECT_DATA_TYPE_FLOAT, .dataValue.floatValue = 50.f};
    ImageEffect_ErrorCode errorCode = OH_EffectFilter_SetValue(filter, OH_EFFECT_FILTER_INTENSITY_KEY, &value);
    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_EffectFilter_SetValue fail!");

  3. 生效滤镜。

    // 生效滤镜效果。
    errorCode = OH_EffectFilter_Render(filter, inputPixelmap, outputPixelmap);

  4. 销毁滤镜实例。

    // 销毁滤镜实例。
    errorCode = OH_EffectFilter_Release(filter);

查询能力

  • 根据滤镜名查询滤镜信息。

    // 创建 OH_EffectFilterInfo 实例。
    OH_EffectFilterInfo *filterInfo = OH_EffectFilterInfo_Create();
    CHECK_AND_RETURN_LOG(filterInfo != nullptr, "OH_EffectFilterInfo_Create fail!");

    // 根据滤镜名查询滤镜能力信息。
    ImageEffect_ErrorCode errorCode = OH_EffectFilter_LookupFilterInfo(OH_EFFECT_BRIGHTNESS_FILTER, filterInfo);
    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_EffectFilter_LookupFilterInfo fail!");

    // 从滤镜能力信息中获取滤镜名。
    char *name = nullptr;
    OH_EffectFilterInfo_GetFilterName(filterInfo, &name);

    // 获取支持的内存类型。
    uint32_t supportedBufferTypesCnt = 0;
    ImageEffect_BufferType *bufferTypeArray = nullptr;
    OH_EffectFilterInfo_GetSupportedBufferTypes(filterInfo, &supportedBufferTypesCnt, &bufferTypeArray);

    // 获取支持的像素类型信息。
    uint32_t supportedFormatsCnt = 0;
    ImageEffect_Format *formatArray = nullptr;
    OH_EffectFilterInfo_GetSupportedFormats(filterInfo, supportedFormatsCnt, &formatArray);

    // 销毁 OH_EffectFilterInfo 实例。
    OH_EffectFilterInfo_Release(filterInfo);

  • 根据条件查询满足条件的滤镜。

    // 查询所有的Filter,需要主动进行资源释放。
    ImageEffect_FilterNames *filterNames = OH_EffectFilter_LookupFilters("Default");

    // ...

    // 释放FilterNames虚拟内存资源。
    OH_EffectFilter_ReleaseFilterNames();

最后呢

很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档 》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。

针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细鸿蒙(OpenHarmony )手册(共计1236页)与鸿蒙(OpenHarmony )开发入门视频,帮助大家在技术的道路上更进一步。

  • 《鸿蒙 (OpenHarmony)开发学习视频》
  • 《鸿蒙生态应用开发V2.0白皮书》
  • 《鸿蒙 (OpenHarmony)开发基础到实战手册》
  • OpenHarmony北向、南向开发环境搭建
  • 《鸿蒙开发基础》
  • 《鸿蒙开发进阶》
  • 《鸿蒙开发实战》

总结

鸿蒙---作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。

并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行! 自↓↓↓拿

相关推荐
程序员飞哥13 小时前
90后大龄程序员失业4个月终于上岸了
后端·面试·程序员
Cyeam14 小时前
爆火的 OpenClaw,赢在生态创新
程序员·开源·openai
databook16 小时前
别让AI代码,变成明天的技术债
人工智能·程序员·ai编程
NineData18 小时前
从业务库到实时分析库,NineData构建MySQL到SelectDB同步链路
数据库·mysql·程序员
UnicornDev18 小时前
【HarmonyOS 6】空状态页面布局设计
华为·harmonyos·arkts·鸿蒙·鸿蒙系统
risc12345620 小时前
复杂社会需要更强的系统整合能力
鸿蒙系统
掉头发的王富贵1 天前
【2026.3.28深圳腾讯云线下活动分享】我用龙虾3分钟完成了文章的抓取,写作,发布一条龙
程序员·线下活动·腾讯
阿里嘎多学长1 天前
2026-03-27 GitHub 热点项目精选
开发语言·程序员·github·代码托管
我要改名叫嘟嘟1 天前
一个大龄程序员的地铁日记(第8期),给予我影响,帮助我改变的书
程序员
陈随易1 天前
农村程序员聊五险一金
前端·后端·程序员