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