1e41f4b71Sopenharmony_ci# Using ImageEffect to Edit Images
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## When to Use
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciThe **ImageEffect** class provides a series of APIs for editing an image. You can use the APIs to implement various filter effects on images of different input types (pixel map, native window, native buffer, or URI).
6e41f4b71Sopenharmony_ciWith the native APIs provided by **ImageEffect**, you can:
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ci- Add a filter or filter chain, set an input image, and make the filter effective on the image.
9e41f4b71Sopenharmony_ci- Customize a filter.
10e41f4b71Sopenharmony_ci- Use a system defined filter.
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci## **Available APIs**
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ciFor details about the APIs, see [ImageEffect](../../reference/apis-image-kit/_image_effect.md).
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ci## How to Develop
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci**Adding Dynamic Link Libraries**
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ciAdd the following libraries to **CMakeLists.txt**.
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci```txt
23e41f4b71Sopenharmony_citarget_link_libraries(entry PUBLIC
24e41f4b71Sopenharmony_ci    libace_ndk.z.so
25e41f4b71Sopenharmony_ci    libimage_effect.so
26e41f4b71Sopenharmony_ci    libpixelmap.so
27e41f4b71Sopenharmony_ci    libnative_window.so
28e41f4b71Sopenharmony_ci    libnative_buffer.so
29e41f4b71Sopenharmony_ci)
30e41f4b71Sopenharmony_ci```
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ciAdd the following dynamic link libraries based on the image type: **libpixelmap.so** for the pixel map type, **libnative_window.so** for the native window type, and **libnative_buffer.so** for the native buffer type.
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ci**Adding the Header Files**
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ci```c++
37e41f4b71Sopenharmony_ci#include <multimedia/image_effect/image_effect.h>
38e41f4b71Sopenharmony_ci#include <multimedia/image_effect/image_effect_filter.h>
39e41f4b71Sopenharmony_ci#include <multimedia/image_effect/image_effect_errors.h>
40e41f4b71Sopenharmony_ci```
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ci### Making a Filter Effective
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ci1. Create an **ImageEffect** instance.
45e41f4b71Sopenharmony_ci
46e41f4b71Sopenharmony_ci    ```c++
47e41f4b71Sopenharmony_ci    // Create an ImageEffect instance, with the alias set to ImageEdit.
48e41f4b71Sopenharmony_ci    OH_ImageEffect *imageEffect = OH_ImageEffect_Create("ImageEdit");
49e41f4b71Sopenharmony_ci    ```
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ci2. Add a filter.
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ci    ```c++
54e41f4b71Sopenharmony_ci    // Add a filter to obtain an OH_EffectFilter instance. You can call this API multiple times to add multiple filters to form a filter chain.
55e41f4b71Sopenharmony_ci    OH_EffectFilter *filter = OH_ImageEffect_AddFilter(imageEffect, OH_EFFECT_BRIGHTNESS_FILTER);
56e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(filter != nullptr, "OH_ImageEffect_AddFilter fail!");
57e41f4b71Sopenharmony_ci    
58e41f4b71Sopenharmony_ci    // Set a filter parameter. For example, set the intensity to 50.
59e41f4b71Sopenharmony_ci    ImageEffect_Any value = { .dataType = ImageEffect_DataType::EFFECT_DATA_TYPE_FLOAT, .dataValue.floatValue = 50.f };
60e41f4b71Sopenharmony_ci    ImageEffect_ErrorCode errorCode = OH_EffectFilter_SetValue(filter, OH_EFFECT_FILTER_INTENSITY_KEY, &value);
61e41f4b71Sopenharmony_ci    ```
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ci3. Set the data to be processed.
64e41f4b71Sopenharmony_ci
65e41f4b71Sopenharmony_ci    **Scenario 1: Set the OH_PixelmapNative input type.**
66e41f4b71Sopenharmony_ci
67e41f4b71Sopenharmony_ci    For details about how to use OH_PixelmapNative, see [PixelMap Data Processing (C/C++)](image-pixelmap-operation-native.md).
68e41f4b71Sopenharmony_ci
69e41f4b71Sopenharmony_ci    ```c++
70e41f4b71Sopenharmony_ci    // Set an input pixel map.
71e41f4b71Sopenharmony_ci    errorCode = OH_ImageEffect_SetInputPixelmap(imageEffect, inputPixelmap);
72e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_SetInputPixelmap fail!");
73e41f4b71Sopenharmony_ci    
74e41f4b71Sopenharmony_ci    // (Optional) Set an output pixel map. If this API is not called, the filter effect directly takes effect on the input pixel map.
75e41f4b71Sopenharmony_ci    errorCode = OH_ImageEffect_SetOutputPixelmap(imageEffect, outputPixelmap);
76e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_SetOutputPixelmap fail!");
77e41f4b71Sopenharmony_ci    ```
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_ci    **Scenario 2: Set the OH_NativeBuffer input type.**
80e41f4b71Sopenharmony_ci
81e41f4b71Sopenharmony_ci    For details about how to use OH_NativeBuffer, see [Native Buffer Development (C/C++)](../../graphics/native-buffer-guidelines.md).
82e41f4b71Sopenharmony_ci
83e41f4b71Sopenharmony_ci    ```c++
84e41f4b71Sopenharmony_ci    // Set an input native buffer.
85e41f4b71Sopenharmony_ci    errorCode = OH_ImageEffect_SetInputNativeBuffer(imageEffect, inputNativeBuffer);
86e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_SetInputNativeBuffer fail!");
87e41f4b71Sopenharmony_ci    
88e41f4b71Sopenharmony_ci    // (Optional) Set an output native buffer. If this API is not called, the filter effect directly takes effect on the input native buffer.
89e41f4b71Sopenharmony_ci    errorCode = OH_ImageEffect_SetOutputNativeBuffer(imageEffect, outputNativeBuffer);
90e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_SetOutputNativeBuffer fail!");
91e41f4b71Sopenharmony_ci    ```
92e41f4b71Sopenharmony_ci
93e41f4b71Sopenharmony_ci    **Scenario 3: Set the URI input type.**
94e41f4b71Sopenharmony_ci
95e41f4b71Sopenharmony_ci    ```c++
96e41f4b71Sopenharmony_ci    // Set an input URI.
97e41f4b71Sopenharmony_ci    errorCode = OH_ImageEffect_SetInputUri(imageEffect, inputUri);
98e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_SetInputUri fail!");
99e41f4b71Sopenharmony_ci    
100e41f4b71Sopenharmony_ci    // (Optional) Set an output URI. If this API is not called, the filter effect directly takes effect on the input URI.
101e41f4b71Sopenharmony_ci    errorCode = OH_ImageEffect_SetOutputUri(imageEffect, outputUri);
102e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_SetOutputUri fail!");
103e41f4b71Sopenharmony_ci    ```
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ci    **Scenario 4: Set the OHNativeWindow input type.**
106e41f4b71Sopenharmony_ci
107e41f4b71Sopenharmony_ci    The following uses camera preview as an example to describe the scenario. The surface ID provided by the **\<XComponent>** for camera preview streams can be converted into an **OHNativeWindow** instance at the native C++ layer.
108e41f4b71Sopenharmony_ci    For details about how to use the **\<XComponent>**, see [XComponent](../../reference/apis-arkui/arkui-ts/ts-basic-components-xcomponent.md).
109e41f4b71Sopenharmony_ci    For details about how to use the native window module, see [OHNativeWindow](../../reference/apis-arkgraphics2d/_native_window.md).
110e41f4b71Sopenharmony_ci    For details about how to use the camera, see [Camera Preview (C/C++)](../camera/native-camera-preview.md).
111e41f4b71Sopenharmony_ci
112e41f4b71Sopenharmony_ci    (1) Add an **\<XComponent>** to the .ets file.
113e41f4b71Sopenharmony_ci
114e41f4b71Sopenharmony_ci     ```ts
115e41f4b71Sopenharmony_ci     XComponent({ 
116e41f4b71Sopenharmony_ci         id: 'xcomponentId', 
117e41f4b71Sopenharmony_ci         type: 'surface',
118e41f4b71Sopenharmony_ci         controller: this.mXComponentController, 
119e41f4b71Sopenharmony_ci         libraryname: 'entry'
120e41f4b71Sopenharmony_ci     })
121e41f4b71Sopenharmony_ci     .onLoad(() => {
122e41f4b71Sopenharmony_ci         // Obtain the surface ID of the <XComponent>.
123e41f4b71Sopenharmony_ci         this.mSurfaceId = this.mXComponentController.getXComponentSurfaceId()
124e41f4b71Sopenharmony_ci 
125e41f4b71Sopenharmony_ci         // Obtain the input surface ID.
126e41f4b71Sopenharmony_ci         this.mSurfaceId = imageEffect.getSurfaceId(this.mSurfaceId)
127e41f4b71Sopenharmony_ci 
128e41f4b71Sopenharmony_ci         // Call the camera API to start preview and transfer the input surface ID to the camera framework.
129e41f4b71Sopenharmony_ci         // ...
130e41f4b71Sopenharmony_ci     })
131e41f4b71Sopenharmony_ci     .width('100%')
132e41f4b71Sopenharmony_ci     .height('100%')
133e41f4b71Sopenharmony_ci     ```
134e41f4b71Sopenharmony_ci
135e41f4b71Sopenharmony_ci    (2) Implement imageEffect.getSurfaceId at the native C++ layer.
136e41f4b71Sopenharmony_ci
137e41f4b71Sopenharmony_ci     ```c++
138e41f4b71Sopenharmony_ci     // Create a NativeWindow instance based on the surface ID. Note that the instance must be released by calling OH_NativeWindow_DestoryNativeWindow when it is no longer needed.
139e41f4b71Sopenharmony_ci     uint64_t outputSurfaceId;
140e41f4b71Sopenharmony_ci     std::istrstream iss(outputSurfaceIdStr);
141e41f4b71Sopenharmony_ci     issue >> outputSurfaceId;
142e41f4b71Sopenharmony_ci     OHNativeWindow *outputNativeWindow = nullptr;
143e41f4b71Sopenharmony_ci     int32_t res = OH_NativeWindow_CreateNativeWindowFromSurfaceId(outputSurfaceId, &outputNativeWindow);
144e41f4b71Sopenharmony_ci     CHECK_AND_RETURN_LOG(res == 0, "OH_NativeWindow_CreateNativeWindowFromSurfaceId fail!");
145e41f4b71Sopenharmony_ci     
146e41f4b71Sopenharmony_ci     // Set an output surface.
147e41f4b71Sopenharmony_ci     ImageEffect_ErrorCode errorCode = OH_ImageEffect_SetOutputSurface(imageEffect, outputNativeWindow);
148e41f4b71Sopenharmony_ci     CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_SetOutputSurface fail!");
149e41f4b71Sopenharmony_ci     
150e41f4b71Sopenharmony_ci     // Obtain the input surface. Note that the obtained inputNativeWindow instance must be released by calling OH_NativeWindow_DestoryNativeWindow when it is no longer needed.
151e41f4b71Sopenharmony_ci     OHNativeWindow *inputNativeWindow = nullptr;
152e41f4b71Sopenharmony_ci     errorCode = OH_ImageEffect_GetInputSurface(imageEffect, &inputNativeWindow);
153e41f4b71Sopenharmony_ci     CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_GetInputSurface fail!");
154e41f4b71Sopenharmony_ci     
155e41f4b71Sopenharmony_ci     // Obtain the surface ID from the inputNativeWindow instance.
156e41f4b71Sopenharmony_ci     uint64_t inputSurfaceId = 0;
157e41f4b71Sopenharmony_ci     res = OH_NativeWindow_GetSurfaceId(inputNativeWindow, &inputSurfaceId);
158e41f4b71Sopenharmony_ci     CHECK_AND_RETURN_LOG(res == 0, "OH_NativeWindow_GetSurfaceId fail!");
159e41f4b71Sopenharmony_ci     
160e41f4b71Sopenharmony_ci     // Convert the surface ID to a string and return the string.
161e41f4b71Sopenharmony_ci     std::string inputSurfaceIdStr = std::to_string(inputSurfaceId);
162e41f4b71Sopenharmony_ci     ```
163e41f4b71Sopenharmony_ci
164e41f4b71Sopenharmony_ci4. Start the image effector.
165e41f4b71Sopenharmony_ci
166e41f4b71Sopenharmony_ci    ```c++
167e41f4b71Sopenharmony_ci    // Start the image effector.
168e41f4b71Sopenharmony_ci    errorCode = OH_ImageEffect_Start(imageEffect);
169e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_Start fail!");
170e41f4b71Sopenharmony_ci    ```
171e41f4b71Sopenharmony_ci
172e41f4b71Sopenharmony_ci5. (Optional) Stop the image effector. This operation is required only in the input surface scenario.
173e41f4b71Sopenharmony_ci
174e41f4b71Sopenharmony_ci    ```c++
175e41f4b71Sopenharmony_ci    // Stop the image effector.
176e41f4b71Sopenharmony_ci    errorCode = OH_ImageEffect_Stop(imageEffect);
177e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_Stop fail!");
178e41f4b71Sopenharmony_ci    ```
179e41f4b71Sopenharmony_ci
180e41f4b71Sopenharmony_ci6. (Optional) Serialize the image effector.
181e41f4b71Sopenharmony_ci
182e41f4b71Sopenharmony_ci    ```c++
183e41f4b71Sopenharmony_ci    char *info = nullptr;
184e41f4b71Sopenharmony_ci    errorCode = OH_ImageEffect_Save(imageEffect, &info);
185e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_Save fail!");
186e41f4b71Sopenharmony_ci    ```
187e41f4b71Sopenharmony_ci
188e41f4b71Sopenharmony_ci7. Destroy the **ImageEffect** instance.
189e41f4b71Sopenharmony_ci
190e41f4b71Sopenharmony_ci    ```c++
191e41f4b71Sopenharmony_ci    // Release the ImageEffect instance.
192e41f4b71Sopenharmony_ci    errorCode = OH_ImageEffect_Release(imageEffect);
193e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result, "OH_ImageEffect_Release fail!");
194e41f4b71Sopenharmony_ci    ```
195e41f4b71Sopenharmony_ci
196e41f4b71Sopenharmony_ci### Customizing a Filter
197e41f4b71Sopenharmony_ci
198e41f4b71Sopenharmony_ciTo implement and register a custom filter, perform the following steps:
199e41f4b71Sopenharmony_ci
200e41f4b71Sopenharmony_ci1. Define **ImageEffect_FilterDelegate**.
201e41f4b71Sopenharmony_ci
202e41f4b71Sopenharmony_ci    ```c++
203e41f4b71Sopenharmony_ci    // Image information struct.
204e41f4b71Sopenharmony_ci    struct EffectBufferInfo {
205e41f4b71Sopenharmony_ci        void *addr = nullptr;
206e41f4b71Sopenharmony_ci        int32_t width = 0;
207e41f4b71Sopenharmony_ci        int32_t height = 0;
208e41f4b71Sopenharmony_ci        int32_t rowSize = 0;
209e41f4b71Sopenharmony_ci        ImageEffect_Format format = ImageEffect_Format::EFFECT_PIXEL_FORMAT_UNKNOWN;
210e41f4b71Sopenharmony_ci    };
211e41f4b71Sopenharmony_ci
212e41f4b71Sopenharmony_ci    // Implement a custom filter.
213e41f4b71Sopenharmony_ci    ImageEffect_FilterDelegate filterDelegate = {
214e41f4b71Sopenharmony_ci        .setValue = [](OH_EffectFilter *filter, const char *key, const ImageEffect_Any *value) {
215e41f4b71Sopenharmony_ci            // Verify the parameters. If the verification is successful, true is returned. Otherwise, false is returned.
216e41f4b71Sopenharmony_ci            // ...
217e41f4b71Sopenharmony_ci            return true;
218e41f4b71Sopenharmony_ci        },
219e41f4b71Sopenharmony_ci        .render = [](OH_EffectFilter *filter, OH_EffectBufferInfo *info, OH_EffectFilterDelegate_PushData pushData) {
220e41f4b71Sopenharmony_ci            return Render(filter, info, pushData);
221e41f4b71Sopenharmony_ci        },
222e41f4b71Sopenharmony_ci        .save = [](OH_EffectFilter *filter, char **info) {
223e41f4b71Sopenharmony_ci            // Obtain the custom filter parameter. In this example, Brightness is the key of the custom filter.
224e41f4b71Sopenharmony_ci            ImageEffect_Any value;
225e41f4b71Sopenharmony_ci            ImageEffect_ErrorCode errorCode = OH_EffectFilter_GetValue(filter, "Brightness", &value);
226e41f4b71Sopenharmony_ci            CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, false, "OH_EffectFilter_GetValue fail!");
227e41f4b71Sopenharmony_ci            
228e41f4b71Sopenharmony_ci            // Generate a key-value pair.
229e41f4b71Sopenharmony_ci            json values;
230e41f4b71Sopenharmony_ci            values["Brightness"] = value.dataValue.floatValue;         
231e41f4b71Sopenharmony_ci            json root;
232e41f4b71Sopenharmony_ci            root["name"] = "CustomBrightness";
233e41f4b71Sopenharmony_ci            root["values"] = values;
234e41f4b71Sopenharmony_ci        
235e41f4b71Sopenharmony_ci           // Convert the JSON object into a string.
236e41f4b71Sopenharmony_ci            // ...
237e41f4b71Sopenharmony_ci
238e41f4b71Sopenharmony_ci            // Assign a serialized string address to *info.
239e41f4b71Sopenharmony_ci            *info = infoStr;
240e41f4b71Sopenharmony_ci            return true;
241e41f4b71Sopenharmony_ci        },
242e41f4b71Sopenharmony_ci        .restore = [](const char *info) {
243e41f4b71Sopenharmony_ci            // Create an OH_EffectFilter instance, in which CustomBrightness is the name of the custom filter.
244e41f4b71Sopenharmony_ci            OH_EffectFilter *filter = OH_EffectFilter_Create("CustomBrightness");
245e41f4b71Sopenharmony_ci            // Parse the JSON string info to obtain the key and value.
246e41f4b71Sopenharmony_ci            // ...
247e41f4b71Sopenharmony_ci        
248e41f4b71Sopenharmony_ci            // Set a filter parameter. value is the parameter parsed based on the JSON string in info.
249e41f4b71Sopenharmony_ci            ImageEffect_ErrorCode errorCode = OH_EffectFilter_SetValue(filter, "Brightness", &value);
250e41f4b71Sopenharmony_ci            
251e41f4b71Sopenharmony_ci            // ...
252e41f4b71Sopenharmony_ci            return filter;
253e41f4b71Sopenharmony_ci        }
254e41f4b71Sopenharmony_ci    };
255e41f4b71Sopenharmony_ci    ```
256e41f4b71Sopenharmony_ci
257e41f4b71Sopenharmony_ci    You can implement the **Render** API in two scenarios.
258e41f4b71Sopenharmony_ci
259e41f4b71Sopenharmony_ci    **Scenario 1: The custom algorithm can directly modify the pixel data in info (for example, the brightness filter).**
260e41f4b71Sopenharmony_ci
261e41f4b71Sopenharmony_ci    ```c++
262e41f4b71Sopenharmony_ci    bool Render(OH_EffectFilter *filter, OH_EffectBufferInfo *info, OH_EffectFilterDelegate_PushData pushData)
263e41f4b71Sopenharmony_ci    {
264e41f4b71Sopenharmony_ci        // Obtain the image information.
265e41f4b71Sopenharmony_ci        EffectBufferInfo inputBufferInfo;
266e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_GetAddr(info, &inputBufferInfo.addr);
267e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_GetWidth(info, &inputBufferInfo.width);
268e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_GetHeight(info, &inputBufferInfo.height);
269e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_GetRowSize(info, &inputBufferInfo.rowSize);
270e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_GetEffectFormat(info, &inputBufferInfo.format);
271e41f4b71Sopenharmony_ci
272e41f4b71Sopenharmony_ci        // Invoke the custom filter algorithm.
273e41f4b71Sopenharmony_ci        ApplyCustomAlgo(inputBufferInfo);
274e41f4b71Sopenharmony_ci
275e41f4b71Sopenharmony_ci        // After the editing is complete, call pushData to directly transfer the original image.
276e41f4b71Sopenharmony_ci        pushData(filter, info);
277e41f4b71Sopenharmony_ci        return true;
278e41f4b71Sopenharmony_ci    }
279e41f4b71Sopenharmony_ci    ```
280e41f4b71Sopenharmony_ci
281e41f4b71Sopenharmony_ci    **Scenario 2: The custom algorithm cannot directly modify the pixel data in info (for example, the crop filter).**
282e41f4b71Sopenharmony_ci
283e41f4b71Sopenharmony_ci    ```c++
284e41f4b71Sopenharmony_ci    bool Render(OH_EffectFilter *filter, OH_EffectBufferInfo *info, OH_EffectFilterDelegate_PushData pushData)
285e41f4b71Sopenharmony_ci    {
286e41f4b71Sopenharmony_ci        // Obtain the image information.
287e41f4b71Sopenharmony_ci        EffectBufferInfo inputBufferInfo;
288e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_GetAddr(info, &inputBufferInfo.addr);
289e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_GetWidth(info, &inputBufferInfo.width);
290e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_GetHeight(info, &inputBufferInfo.height);
291e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_GetRowSize(info, &inputBufferInfo.rowSize);
292e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_GetEffectFormat(info, &inputBufferInfo.format);
293e41f4b71Sopenharmony_ci
294e41f4b71Sopenharmony_ci        // Create output pixel information.
295e41f4b71Sopenharmony_ci        EffectBufferInfo outputBufferInfo = CreateOutputBufferInfo(inputBufferInfo);
296e41f4b71Sopenharmony_ci
297e41f4b71Sopenharmony_ci        // Invoke the custom filter algorithm.
298e41f4b71Sopenharmony_ci        ApplyCustomAlgo(inputBufferInfo, outputBufferInfo);
299e41f4b71Sopenharmony_ci
300e41f4b71Sopenharmony_ci        // Generate outputOhInfo.
301e41f4b71Sopenharmony_ci        OH_EffectBufferInfo *outputOhInfo = OH_EffectBufferInfo_Create();
302e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_SetAddr(outputOhInfo, outputBufferInfo.addr);
303e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_SetWidth(outputOhInfo, outputBufferInfo.width);
304e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_SetHeight(outputOhInfo, outputBufferInfo.height);
305e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_SetRowSize(outputOhInfo, outputBufferInfo.rowSize);
306e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_SetEffectFormat(outputOhInfo, outputBufferInfo.format);
307e41f4b71Sopenharmony_ci
308e41f4b71Sopenharmony_ci        // Call pushData to transfer outputOhInfo after editing.
309e41f4b71Sopenharmony_ci        pushData(filter, outputOhInfo);
310e41f4b71Sopenharmony_ci
311e41f4b71Sopenharmony_ci        // Release resources.
312e41f4b71Sopenharmony_ci        OH_EffectBufferInfo_Release(outputOhInfo);
313e41f4b71Sopenharmony_ci        ReleaseOutputBuffer(outputBufferInfo.addr);
314e41f4b71Sopenharmony_ci
315e41f4b71Sopenharmony_ci        return true;
316e41f4b71Sopenharmony_ci    }
317e41f4b71Sopenharmony_ci    ```
318e41f4b71Sopenharmony_ci
319e41f4b71Sopenharmony_ci2. Generate custom filter information.
320e41f4b71Sopenharmony_ci
321e41f4b71Sopenharmony_ci    ```c++
322e41f4b71Sopenharmony_ci    // Create an OH_EffectFilterInfo instance.
323e41f4b71Sopenharmony_ci    OH_EffectFilterInfo *customFilterInfo = OH_EffectFilterInfo_Create();
324e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(customFilterInfo != nullptr, "OH_EffectFilter_GetValue fail!");
325e41f4b71Sopenharmony_ci    
326e41f4b71Sopenharmony_ci    // Set the name of the custom filter.
327e41f4b71Sopenharmony_ci    OH_EffectFilterInfo_SetFilterName(customFilterInfo, "CustomBrightness");
328e41f4b71Sopenharmony_ci    
329e41f4b71Sopenharmony_ci    // Set the buffer types supported by the custom filter.
330e41f4b71Sopenharmony_ci    ImageEffect_BufferType bufferTypeArray[] = { ImageEffect_BufferType::EFFECT_BUFFER_TYPE_PIXEL };
331e41f4b71Sopenharmony_ci    OH_EffectFilterInfo_SetSupportedBufferTypes(customFilterInfo, sizeof(bufferTypeArray) / sizeof(ImageEffect_BufferType), bufferTypeArray);
332e41f4b71Sopenharmony_ci    
333e41f4b71Sopenharmony_ci    // Set the pixel formats supported by the custom filter.
334e41f4b71Sopenharmony_ci    ImageEffect_Format formatArray[] = { ImageEffect_Format::EFFECT_PIXEL_FORMAT_RGBA8888 };
335e41f4b71Sopenharmony_ci    OH_EffectFilterInfo_SetSupportedFormats(customFilterInfo, sizeof(formatArray) / sizeof(ImageEffect_Format), formatArray);
336e41f4b71Sopenharmony_ci    ```
337e41f4b71Sopenharmony_ci
338e41f4b71Sopenharmony_ci3. Register **ImageEffect_FilterDelegate** with the image effector.
339e41f4b71Sopenharmony_ci
340e41f4b71Sopenharmony_ci    ```c++
341e41f4b71Sopenharmony_ci    // Register the custom filter.
342e41f4b71Sopenharmony_ci    ImageEffect_ErrorCode errorCode = OH_EffectFilter_Register(customFilterInfo, &filterDelegate);
343e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_EffectFilter_Register fail!");
344e41f4b71Sopenharmony_ci    ```
345e41f4b71Sopenharmony_ci
346e41f4b71Sopenharmony_ci### Using a System Defined Filter
347e41f4b71Sopenharmony_ci
348e41f4b71Sopenharmony_ci1. Create a filter.
349e41f4b71Sopenharmony_ci
350e41f4b71Sopenharmony_ci    ```c++
351e41f4b71Sopenharmony_ci    // Create a filter, for example, a contrast filter.
352e41f4b71Sopenharmony_ci    OH_EffectFilter *filter = OH_EffectFilter_Create(OH_EFFECT_CONTRAST_FILTER);
353e41f4b71Sopenharmony_ci    ```
354e41f4b71Sopenharmony_ci
355e41f4b71Sopenharmony_ci2. Set a filter parameter.
356e41f4b71Sopenharmony_ci
357e41f4b71Sopenharmony_ci    ```c++
358e41f4b71Sopenharmony_ci    // Set a filter parameter. For example, set the intensity to 50.
359e41f4b71Sopenharmony_ci    ImageEffect_Any value = {.dataType = ImageEffect_DataType::EFFECT_DATA_TYPE_FLOAT, .dataValue.floatValue = 50.f};
360e41f4b71Sopenharmony_ci    ImageEffect_ErrorCode errorCode = OH_EffectFilter_SetValue(filter, OH_EFFECT_FILTER_INTENSITY_KEY, &value);
361e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_EffectFilter_SetValue fail!");
362e41f4b71Sopenharmony_ci    ```
363e41f4b71Sopenharmony_ci
364e41f4b71Sopenharmony_ci3. Make the filter take effect.
365e41f4b71Sopenharmony_ci
366e41f4b71Sopenharmony_ci    ```c++
367e41f4b71Sopenharmony_ci    // Start rendering with the filter.
368e41f4b71Sopenharmony_ci    errorCode = OH_EffectFilter_Render(filter, inputPixelmap, outputPixelmap);
369e41f4b71Sopenharmony_ci    ```
370e41f4b71Sopenharmony_ci
371e41f4b71Sopenharmony_ci4. Destroy the filter instance.
372e41f4b71Sopenharmony_ci
373e41f4b71Sopenharmony_ci    ```c++
374e41f4b71Sopenharmony_ci    // Destroy the filter instance.
375e41f4b71Sopenharmony_ci    errorCode = OH_EffectFilter_Release(filter);
376e41f4b71Sopenharmony_ci    ```
377e41f4b71Sopenharmony_ci
378e41f4b71Sopenharmony_ci### Query Capabilities
379e41f4b71Sopenharmony_ci
380e41f4b71Sopenharmony_ci- Query filter information based on the filter name.
381e41f4b71Sopenharmony_ci
382e41f4b71Sopenharmony_ci    ```c++
383e41f4b71Sopenharmony_ci    // Create an OH_EffectFilterInfo instance.
384e41f4b71Sopenharmony_ci    OH_EffectFilterInfo *filterInfo = OH_EffectFilterInfo_Create();
385e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(filterInfo != nullptr, "OH_EffectFilterInfo_Create fail!");
386e41f4b71Sopenharmony_ci
387e41f4b71Sopenharmony_ci    // Query the filter information based on the filter name.
388e41f4b71Sopenharmony_ci    ImageEffect_ErrorCode errorCode = OH_EffectFilter_LookupFilterInfo(OH_EFFECT_BRIGHTNESS_FILTER, filterInfo);
389e41f4b71Sopenharmony_ci    CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_EffectFilter_LookupFilterInfo fail!");
390e41f4b71Sopenharmony_ci
391e41f4b71Sopenharmony_ci    // Obtain the filter name from the filter information.
392e41f4b71Sopenharmony_ci    char *name = nullptr;
393e41f4b71Sopenharmony_ci    OH_EffectFilterInfo_GetFilterName(filterInfo, &name);
394e41f4b71Sopenharmony_ci
395e41f4b71Sopenharmony_ci    // Obtain the supported buffer types.
396e41f4b71Sopenharmony_ci    uint32_t supportedBufferTypesCnt = 0;
397e41f4b71Sopenharmony_ci    ImageEffect_BufferType *bufferTypeArray = nullptr;
398e41f4b71Sopenharmony_ci    OH_EffectFilterInfo_GetSupportedBufferTypes(filterInfo, &supportedBufferTypesCnt, &bufferTypeArray);
399e41f4b71Sopenharmony_ci
400e41f4b71Sopenharmony_ci    // Obtain the supported pixel formats.
401e41f4b71Sopenharmony_ci    uint32_t supportedFormatsCnt = 0;
402e41f4b71Sopenharmony_ci    ImageEffect_Format *formatArray = nullptr;
403e41f4b71Sopenharmony_ci    OH_EffectFilterInfo_GetSupportedFormats(filterInfo, supportedFormatsCnt, &formatArray);
404e41f4b71Sopenharmony_ci
405e41f4b71Sopenharmony_ci    // Destroy the OH_EffectFilterInfo instance.
406e41f4b71Sopenharmony_ci    OH_EffectFilterInfo_Release(filterInfo);
407e41f4b71Sopenharmony_ci    ```
408e41f4b71Sopenharmony_ci
409e41f4b71Sopenharmony_ci- Query filters that meet given conditions.
410e41f4b71Sopenharmony_ci
411e41f4b71Sopenharmony_ci    ```c++
412e41f4b71Sopenharmony_ci    // Query all filters. Resources need to be released.
413e41f4b71Sopenharmony_ci    ImageEffect_FilterNames *filterNames = OH_EffectFilter_LookupFilters("Default");
414e41f4b71Sopenharmony_ci    
415e41f4b71Sopenharmony_ci    // ...
416e41f4b71Sopenharmony_ci    
417e41f4b71Sopenharmony_ci    // Release virtual memory resources by filter names.
418e41f4b71Sopenharmony_ci    OH_EffectFilter_ReleaseFilterNames();
419e41f4b71Sopenharmony_ci    ```
420e41f4b71Sopenharmony_ci
421