1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16// [Start pixelmap_import_BusinessError_module] 17import { BusinessError } from '@kit.BasicServicesKit'; 18// [End pixelmap_importBusinessError_module] 19// [Start pixelmap_import_image_module_in_decode] 20import { image } from '@kit.ImageKit'; 21// [End pixelmap_import_image_module_in_decode] 22// [Start pixelmap_import_fileio_modulef] 23import { fileIo as fs } from '@kit.CoreFileKit'; 24// [End pixelmap_import_fileio_modulef] 25// [Start pixelmap_get_resource_manager] 26// 导入resourceManager资源管理器 27// [Start pixelmap_import_resource_manager_modulef] 28import { resourceManager } from '@kit.LocalizationKit'; 29// [End pixelmap_import_resource_manager_modulef] 30import Logger from './Logger'; 31 32const context: Context = getContext(this); 33// 获取resourceManager资源管理 34const resourceMgr: resourceManager.ResourceManager = context.resourceManager; 35// [End pixelmap_get_resource_manager] 36 37export class Decode { 38 /** 39 * 通过沙箱路径直接获取文件资源实例 40 * 41 * @param fileName - 文件名称。 42 * @returns 图片资源实例。 43 **/ 44 public getImageSourceByFilePath(fileName: string): image.ImageSource { 45 // [Start pixelmap_get_image_by_filepath] 46 const context: Context = getContext(this); 47 // fileName可使用'/test.jpg',也可以根据实际环境传入其他图片名 48 const filePath: string = context.cacheDir + fileName; 49 // [End pixelmap_get_image_by_filepath] 50 // path为已获得的沙箱路径 51 // [Start pixelmap_create_image_source_by_file_path] 52 const imageSource: image.ImageSource = image.createImageSource(filePath); 53 // [End pixelmap_create_image_source_by_file_path] 54 return imageSource; 55 } 56 57 /** 58 * 通过沙箱内文件的文件描述符获取文件资源实例 59 * 60 * @param fileName - 文件名称。 61 * @returns 图片资源实例。 62 **/ 63 public getImageSourceByFd(fileName: string): image.ImageSource { 64 // [Start pixelmap_get_image_by_fd] 65 const context: Context = getContext(this); 66 // fileName可使用'/test.jpg',也可以根据实际环境传入其他图片名 67 const filePath = context.cacheDir + fileName; 68 const file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_WRITE); 69 const fd: number = file?.fd; 70 // [End pixelmap_get_image_by_fd] 71 // fd为已获得的文件描述符 72 // [Start pixelmap_create_image_source_by_fd] 73 const imageSource: image.ImageSource = image.createImageSource(fd); 74 // [End pixelmap_create_image_source_by_fd] 75 return imageSource; 76 } 77 78 /** 79 * 通过资源管理器获取资源文件(rawfile)的ArrayBuffer,再通过ArrayBuffer获取文件资源实例 80 * 81 * @param fileName - 文件名称。 82 * @returns 图片资源实例。 83 **/ 84 public getImageSourceByArrayBuffer(fileName: string): Promise<image.ImageSource> { 85 // [Start pixelmap_get_resource_manager_in_arraybuffer] 86 const context: Context = getContext(this); 87 const resourceMgr: resourceManager.ResourceManager = context.resourceManager; 88 // [End pixelmap_get_resource_manager_in_arraybuffer] 89 return new Promise((resolve, reject) => { 90 // [Start pixelmap_get_arraybuffer_of_resource] 91 // fileName可使用'/test.jpg',也可以根据实际环境传入其他图片名 92 resourceMgr.getRawFileContent(fileName).then((fileData: Uint8Array) => { 93 Logger.info('getImageSourceByArrayBuffer: ', 'Succeeded in getting RawFileContent'); 94 // 获取图片的ArrayBuffer 95 const buffer = fileData.buffer.slice(0); 96 // [Start pixelmap_create_image_source_by_arraybuffer] 97 const imageSource: image.ImageSource = image.createImageSource(buffer); 98 // [End pixelmap_create_image_source_by_arraybuffer] 99 resolve(imageSource); 100 }).catch((err: BusinessError) => { 101 Logger.error('getImageSourceByArrayBuffer: ', 'Failed to get RawFileContent'); 102 reject(err); 103 }); 104 // [End pixelmap_get_arraybuffer_of_resource] 105 }); 106 } 107 108 /** 109 * 通过资源管理器获取资源文件(rawfile)的RawFileDescriptor,再通过RawFileDescriptor获取文件资源实例 110 * 111 * @param fileName - 文件名称。 112 * @returns 图片资源实例。 113 **/ 114 public getImageSourceByRawFileDescriptor(fileName: string): Promise<image.ImageSource> { 115 // [Start pixelmap_get_resource_manager_in_raw_file_descriptor] 116 // 获取resourceManager资源管理器 117 const context: Context = getContext(this); 118 const resourceMgr: resourceManager.ResourceManager = context.resourceManager; 119 // [End pixelmap_get_resource_manager_in_raw_file_descriptor] 120 return new Promise((resolve, reject) => { 121 // [Start pixelmap_get_rawfd_by_resource_manager] 122 // fileName可使用'/test.jpg',也可以根据实际环境传入其他图片名 123 resourceMgr.getRawFd(fileName).then((rawFileDescriptor: resourceManager.RawFileDescriptor) => { 124 Logger.info('getImageSourceByRawFileDescriptor: ', 'Succeeded in getting RawFileDescriptor'); 125 // [Start pixelmap_create_image_source_by_rawfd] 126 const imageSource: image.ImageSource = image.createImageSource(rawFileDescriptor); 127 // [End pixelmap_create_image_source_by_rawfd] 128 resolve(imageSource); 129 }).catch((err: BusinessError) => { 130 Logger.error('getImageSourceByRawFileDescriptor: ', 'Failed to get RawFileDescriptor'); 131 reject(err); 132 }); 133 // [End pixelmap_get_rawfd_by_resource_manager] 134 }); 135 } 136 137 138 /** 139 * 设置期望的format进行解码 140 * 141 * @param imageSource - 图片资源实例。 142 * @returns 位图操作实例。 143 **/ 144 public decodeByFormatWithParameter(imageSource: image.ImageSource): Promise<image.PixelMap> { 145 Logger.info('getPixelMap DecodeByFormatWithParameter Start'); 146 let decodingOptions: image.DecodingOptions = { 147 editable: true, 148 desiredPixelFormat: 3, // 以RGBA_8888格式进行解码 149 } 150 return new Promise((resolve, reject) => { 151 // 创建pixelMap 152 imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => { 153 Logger.info('decodeByFormatWithParameter: ', 'Succeeded in creating PixelMap'); 154 resolve(pixelMap); 155 }).catch((err: BusinessError) => { 156 Logger.error('decodeByFormatWithParameter: ', 'Failed to create PixelMap'); 157 reject(err); 158 }); 159 }); 160 } 161 162 /** 163 * HDR图片解码 164 * 165 * @param imageSource - 图片资源实例。 166 * @returns 位图操作对象。 167 **/ 168 public decodeByAutoWithParameter(imageSource: image.ImageSource): Promise<image.PixelMap> { 169 let decodingOptions: image.DecodingOptions = { 170 //设置为AUTO会根据图片资源格式解码,如果图片资源为HDR资源则会解码为HDR的pixelmap。 171 desiredDynamicRange: image.DecodingDynamicRange.AUTO, 172 } 173 return new Promise((resolve, reject) => { 174 // 创建pixelMap 175 imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => { 176 Logger.info('decodeByAutoWithParameter: ', 'Succeeded in creating PixelMap'); 177 // 判断pixelmap是否为hdr内容 178 let info = pixelMap.getImageInfoSync(); 179 Logger.info('pixelmap isHdr: ', String(info.isHdr)); 180 resolve(pixelMap); 181 }).catch((err: BusinessError) => { 182 Logger.error('decodeByAutoWithParameter: ', 'Failed to create PixelMap'); 183 reject(err); 184 }); 185 }); 186 } 187 188 /** 189 * 设置期望的format直接解码resources下的图片资源 190 * 191 * @returns 位图操作对象。 192 **/ 193 public async decodeByFormat(): Promise<image.PixelMap> { 194 Logger.info('getPixelMap DecodeByFormat Start'); 195 // [Start pixelmap_decode_using_RGBA_8888_format] 196 let img = await getContext(this).resourceManager.getMediaContent($r('app.media.image')); 197 let imageSource: image.ImageSource = image.createImageSource(img.buffer.slice(0)); 198 let decodingOptions: image.DecodingOptions = { 199 editable: true, 200 desiredPixelFormat: 3, // 以RGBA_8888格式进行解码 201 } 202 return new Promise((resolve, reject) => { 203 // 创建pixelMap 204 imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => { 205 Logger.info('decodeByFormat: ', 'Succeeded in creating PixelMap'); 206 resolve(pixelMap); 207 }).catch((err: BusinessError) => { 208 Logger.error('decodeByFormat: ', 'Failed to create PixelMap'); 209 reject(err); 210 }); 211 // [Start pixelmap_release_image_source] 212 imageSource.release(); 213 // [End pixelmap_release_image_source] 214 }); 215 // [End pixelmap_decode_using_RGBA_8888_format] 216 } 217 218 /** 219 * 自动推断解码方式,解码resources下的图片资源 220 * 221 * @returns 位图操作对象。 222 **/ 223 public async decodeByAuto(): Promise<image.PixelMap> { 224 // [Start pixelmap_decode_using_auto_format] 225 let img = await getContext(this).resourceManager.getMediaContent($r('app.media.CUVAHdr')); 226 let imageSource: image.ImageSource = image.createImageSource(img.buffer.slice(0)); 227 let decodingOptions: image.DecodingOptions = { 228 //设置为AUTO会根据图片资源格式解码,如果图片资源为HDR资源则会解码为HDR的pixelmap。 229 desiredDynamicRange: image.DecodingDynamicRange.AUTO, 230 } 231 return new Promise((resolve, reject) => { 232 // 创建pixelMap 233 imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => { 234 Logger.info('decodeByAuto: ', 'Succeeded in creating PixelMap'); 235 // 判断pixelmap是否为hdr内容 236 let info = pixelMap.getImageInfoSync(); 237 Logger.info('pixelmap isHdr: ', String(info.isHdr)); 238 resolve(pixelMap); 239 }).catch((err: BusinessError) => { 240 Logger.error('decodeByAuto: ', 'Failed to create PixelMap'); 241 reject(err); 242 }); 243 imageSource.release(); 244 }); 245 // [End pixelmap_decode_using_auto_format] 246 } 247 248 /** 249 * 开发示例方式一,通过ArrayBuffer解码rawfile下的图片资源 250 * 251 * @returns 位图操作对象。 252 **/ 253 public decodeSample_1(): Promise<image.PixelMap> { 254 return new Promise((resolve, reject) => { 255 // [Start pixelmap_create_image_source_by_text_jpg_arraybuffer] 256 resourceMgr.getRawFileContent('test.jpg').then((fileData: Uint8Array) => { 257 Logger.info('decodeSample_1: ', 'Succeeded in getting RawFileContent'); 258 // 获取图片的ArrayBuffer 259 const buffer = fileData.buffer.slice(0); 260 const imageSource: image.ImageSource = image.createImageSource(buffer); 261 // [Start pixelmap_create_pixelmap] 262 imageSource.createPixelMap().then((pixelMap: image.PixelMap) => { 263 Logger.info('decodeSample_1: ', 'Succeeded in creating PixelMap'); 264 resolve(pixelMap); 265 }).catch((err: BusinessError) => { 266 Logger.error('decodeSample_1: ', 'Failed to create PixelMap'); 267 reject(err); 268 }); 269 // [End pixelmap_create_pixelmap] 270 imageSource.release(); 271 }).catch((err: BusinessError) => { 272 Logger.error('decodeSample_1: ', 'Failed to get RawFileContent'); 273 reject(err); 274 }); 275 // [End pixelmap_create_image_source_by_text_jpg_arraybuffer] 276 }); 277 } 278 279 /** 280 * 开发示例方式二,通过RawFileDescriptor解码rawfile下的图片资源 281 * 282 * @returns 位图操作对象。 283 **/ 284 public decodeSample_2(): Promise<image.PixelMap> { 285 return new Promise((resolve, reject) => { 286 resourceMgr.getRawFd('test.jpg').then((rawFileDescriptor: resourceManager.RawFileDescriptor) => { 287 Logger.info('decodeSample_2: ', 'Succeeded in getting RawFd'); 288 const imageSource: image.ImageSource = image.createImageSource(rawFileDescriptor); 289 imageSource.createPixelMap().then((pixelMap: image.PixelMap) => { 290 Logger.info('decodeSample_2: ', 'Succeeded in creating PixelMap'); 291 resolve(pixelMap); 292 }).catch((err: BusinessError) => { 293 Logger.error('decodeSample_2: ', 'Failed to create PixelMap'); 294 reject(err); 295 }); 296 imageSource.release(); 297 }).catch((err: BusinessError) => { 298 Logger.error('decodeSample_2: ', 'Failed to get RawFileContent'); 299 reject(err); 300 }); 301 }); 302 } 303} 304