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