1# Using Image to Decode Images
2
3Image decoding refers to the process of decoding an archived image in a supported format into a [PixelMap](image-overview.md) for image display or [processing](image-transformation.md). Currently, the following image formats are supported: JPEG, PNG, GIF, WebP, BMP, SVG, ICO, DNG, and HEIF (depending on the hardware).
4
5## How to Develop
6
7Read [Image](../../reference/apis-image-kit/js-apis-image.md) for APIs related to image decoding.
8
9### Adding Dependencies
10
11Open the **src/main/cpp/CMakeLists.txt** file of the native project, add **libace_napi.z.so**, **libpixelmap_ndk.z.so**, **libimage_source_ndk.z.so**, **librawfile.z.so**, and **libhilog_ndk.z.so** (on which the native log APIs depend) to the **target_link_libraries** dependency.
12
13```txt
14target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so libpixelmap_ndk.z.so libimage_source_ndk.z.so librawfile.z.so)
15```
16
17### Adding API Mappings
18
19Open the **src/main/cpp/hello.cpp** file, and add the mapping of the **getSyncPixelMap** function to the **Init** function. The **getSyncPixelMap** function is used to generate a PixelMap in synchronous mode. The code is as follows:
20
21```c++
22EXTERN_C_START
23static napi_value Init(napi_env env, napi_value exports)
24{
25    napi_property_descriptor desc[] = {
26        { "getSyncPixelMap", nullptr, getSyncPixelMap, nullptr, nullptr, nullptr, napi_default, nullptr },
27    };
28
29    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
30    return exports;
31}
32EXTERN_C_END
33```
34
35### Calling APIs on the JS Side
36
371. Open **src\main\cpp\types\*libentry*\index.d.ts** (where **libentry** varies according to the project name), and import the following files:
38
39    ```js
40    import { image } from '@kit.ImageKit';
41    import { resourceManager } from '@kit.LocalizationKit';
42
43    // Synchronous call. The input parameters are the resource manager and image resource name, and a PixelMap is returned.
44    export const getSyncPixelMap: (resMgr: resourceManager.ResourceManager, src: string) => image.PixelMap;
45    ```
46
472. Prepare an image resource file, named **example.jpg** in this example, and import it to **src\main\resources\rawfile\**.
48
493. Open **src\main\ets\pages\index.ets**, import ***libentry*.so** (where **libentry** varies according to the project name), call the native APIs, and pass in the JS resource object. The following is an example:
50
51    ```js
52    import testNapi from 'libentry.so'
53    import { image } from '@kit.ImageKit';
54
55    @Entry
56    @Component
57    struct Index {
58      @State pixelMap : PixelMap | undefined = undefined;
59      aboutToAppear() {
60         // Call the custom getSyncPixelMap function to obtain a PixelMap.
61         this.pixelMap = testNapi.getSyncPixelMap(getContext(this).resourceManager, "example.jpg")
62      }
63
64      build() {
65         Row() {
66            Column() {
67            Image(this.pixelMap)
68               .width(100)
69               .height(100)
70            }
71            .width('100%')
72         }
73         .height('100%')
74      }
75   }
76    ```
77
78### Calling the Native APIs
79
80For details about the APIs, see [Image](../../reference/apis-image-kit/image.md).
81
82Obtain the JS resource object from the **hello.cpp** file and convert it to a native resource object. Then you can call native APIs.
83
84**Adding Reference Files**
85
86   ```c++
87      // Include the image framework, raw file, raw file management, and log print header files.
88      #include <cstdlib>
89      #include <cstring>
90      #include <multimedia/image_framework/image_source_mdk.h>
91      #include <multimedia/image_framework/image_pixel_map_mdk.h>
92      #include <rawfile/raw_file.h>
93      #include <rawfile/raw_file_manager.h>
94      #include <hilog/log.h>
95
96      static napi_value getSyncPixelMap(napi_env env, napi_callback_info info)
97      {
98         size_t argc = 2;
99         napi_value args[2] = {nullptr};
100
101         napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
102
103         napi_valuetype srcType;
104         napi_typeof(env, args[0], &srcType);
105
106         // The input parameter args[0] indicates the resource manager, which is used to initialize the resource manager at the native layer.
107         NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, args[0]);
108
109         size_t strSize;
110         char srcBuf[2048];
111         // The input parameter args[1] indicates the file name.
112         napi_get_value_string_utf8(env, args[1], srcBuf, sizeof(srcBuf), &strSize);
113
114         // Use the resource manager to open the raw file.
115         RawFile * rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, srcBuf);
116         if (rawFile != NULL) {
117            // Obtain the file size and read data.
118            long len = OH_ResourceManager_GetRawFileSize(rawFile);
119            uint8_t * data = static_cast<uint8_t *>(malloc(len));
120            int res = OH_ResourceManager_ReadRawFile(rawFile, data, len);
121
122            OhosImageSource imageSource_c;
123            imageSource_c.buffer = data;
124            imageSource_c.bufferSize = len;
125
126            OhosImageSourceOps ops{};
127            napi_value imageSource;
128            napi_value pixelMap;
129
130            // Create an ImageSource object using the read raw data.
131            int32_t ret = OH_ImageSource_Create(env, &imageSource_c, &ops, &imageSource);
132
133            // Initialize the ImageSource object at the native layer.
134            ImageSourceNative * imageSourceNative_c = OH_ImageSource_InitNative(env, imageSource);
135            OhosImageDecodingOps decodingOps{};
136            // Create a PixelMap.
137            OH_ImageSource_CreatePixelMap(imageSourceNative_c, &decodingOps, &pixelMap);
138
139            // The following APIs are used for the GIF format.
140            // napi_value pixelMapList;
141            // OH_ImageSource_CreatePixelMapList(imageSourceNative_c, &decodingOps, &pixelMapList);
142            // OhosImageSourceDelayTimeList list{};
143            // OH_ImageSource_GetDelayTime(imageSourceNative_c, &list);
144            // uint32_t count;
145            // OH_ImageSource_GetFrameCount(imageSourceNative_c, &count);
146
147            OhosImageSourceInfo info{};
148            // Read the image width and height.
149            OH_ImageSource_GetImageInfo(imageSourceNative_c, 0, &info);
150            OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[decode]", "imageInfo width:%{public}d , height:%{public}d", info.size.width, info.size.height);
151
152            // Read the ImageWidth configuration of the image source and print logs.
153            OhosImageSourceProperty target;
154            char exifKey_c[] = "ImageWidth";
155            target.size = strlen(exifKey_c);
156            target.value = exifKey_c;
157
158            OhosImageSourceProperty response{};
159            response.size = 20;
160            response.value = static_cast<char *>(malloc(20));
161            OH_ImageSource_GetImageProperty(imageSourceNative_c, &target, &response);
162            OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[decode]", "ImageProperty width after modify:%{public}s", response.value);
163
164            // After the processing is complete, release resources at the native layer.
165            OH_ImageSource_Release(imageSourceNative_c);
166            OH_ResourceManager_CloseRawFile(rawFile);
167            return pixelMap;
168         }
169         OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);
170         return nullptr;
171      }
172   ```
173
174The image framework supports incremental decoding. The method is as follows:
175
176   ```c++
177      // Include the image framework, raw file, raw file management, and log print header files.
178      #include <cstdlib>
179      #include <cstring>
180      #include <multimedia/image_framework/image_source_mdk.h>
181      #include <multimedia/image_framework/image_pixel_map_mdk.h>
182      #include <rawfile/raw_file.h>
183      #include <rawfile/raw_file_manager.h>
184      #include <hilog/log.h>
185
186      static napi_value getSyncPixelMap(napi_env env, napi_callback_info info)
187      {
188         size_t argc = 2;
189         napi_value args[2] = {nullptr};
190
191         napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
192
193         napi_valuetype srcType;
194         napi_typeof(env, args[0], &srcType);
195
196         // The input parameter args[0] indicates the resource manager, which is used to initialize the resource manager at the native layer.
197         NativeResourceManager * mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, args[0]);
198
199         size_t strSize;
200         char srcBuf[2048];
201         // The input parameter args[1] indicates the file name.
202         napi_get_value_string_utf8(env, args[1], srcBuf, sizeof(srcBuf), &strSize);
203
204         // Use the resource manager to open the raw file.
205         RawFile * rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, srcBuf);
206         if (rawFile != NULL) {
207            // Obtain the file size. If the file size is greater than 2048 bytes, incremental decoding is performed. Otherwise, full decoding is performed.
208            long len = OH_ResourceManager_GetRawFileSize(rawFile);
209            if (len > 2048) {
210               uint8_t * data = static_cast<uint8_t *>(malloc(len));
211               // Read all data in the file.
212               int res = OH_ResourceManager_ReadRawFile(rawFile, data, len);
213
214               uint8_t * holderdata = static_cast<uint8_t *>(malloc(len));
215
216               OhosImageSource imageSource_c;
217               // A buffer of imageSource_c is allocated, but no data is filled in.
218               imageSource_c.buffer = holderdata;
219               imageSource_c.bufferSize = len;
220               OhosImageSourceOps ops{};
221               napi_value imageSource;
222               // Initialize the incremental ImageSource object.
223               OH_ImageSource_CreateIncremental(env, &imageSource_c, &ops, &imageSource);
224
225               // Initialize the ImageSource object at the native layer.
226               ImageSourceNative * imageSourceNative_c = OH_ImageSource_InitNative(env, imageSource);
227
228               // The following simulates segment loading. Segments are loaded twice. 2048 bytes of data are loaded for the first time, and the remaining data is loaded for the second time.
229               OhosImageSourceUpdateData firstData{};
230               firstData.buffer = data; // Image data.
231               firstData.bufferSize = len; // Total size of the image data.
232               firstData.isCompleted = false;
233               firstData.offset = 0; // The first loading starts from the very beginning.
234               firstData.updateLength = 2048; // 2048 bytes are loaded for the first time.
235               OH_ImageSource_UpdateData(imageSourceNative_c, &firstData);
236
237               OhosImageSourceUpdateData secondData{};
238               secondData.buffer = data;
239               secondData.bufferSize = len;
240               secondData.isCompleted = true; // Last loading, to indicating that loading is complete.
241               secondData.offset = 2048; // 2048 bytes of data have been loaded. Offset the data to load for the second time.
242               secondData.updateLength = len - 2048; // Load the remaining data for the second time.
243               OH_ImageSource_UpdateData(imageSourceNative_c, &secondData);
244
245               napi_value pixelMap;
246               OhosImageDecodingOps decodingOps{};
247               decodingOps.index = 0;
248               // Create a PixelMap.
249               OH_ImageSource_CreatePixelMap(imageSourceNative_c, &decodingOps, &pixelMap);
250
251               // After the processing is complete, release resources at the native layer.
252               OH_ImageSource_Release(imageSourceNative_c);
253               OH_ResourceManager_CloseRawFile(rawFile);
254               return pixelMap;
255            }
256            // Read all data in the raw file.
257            uint8_t * data = static_cast<uint8_t *>(malloc(len));
258            int res = OH_ResourceManager_ReadRawFile(rawFile, data, len);
259
260            OhosImageSource imageSource_c;
261            imageSource_c.buffer = data;
262            imageSource_c.bufferSize = len;
263
264            OhosImageSourceOps ops{};
265            napi_value imageSource;
266            napi_value pixelMap;
267
268            // Create an ImageSource object using the read raw data.
269            int32_t ret = OH_ImageSource_Create(env, &imageSource_c, &ops, &imageSource);
270
271            // Initialize the ImageSource object at the native layer.
272            ImageSourceNative * imageSourceNative_c = OH_ImageSource_InitNative(env, imageSource);
273            OhosImageDecodingOps decodingOps{};
274
275            // Create a PixelMap.
276            OH_ImageSource_CreatePixelMap(imageSourceNative_c, &decodingOps, &pixelMap);
277
278            // After the processing is complete, release resources at the native layer.
279            OH_ImageSource_Release(imageSourceNative_c);
280            OH_ResourceManager_CloseRawFile(rawFile);
281            return pixelMap;
282         }
283         OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);
284         return nullptr;
285      }
286   ```
287