1# 使用ImageSource完成图片解码 2<!--Kit: Image Kit--> 3<!--Subsystem: Multimedia--> 4<!--Owner: @aulight02--> 5<!--Designer: @liyang_bryan--> 6<!--Tester: @xchaosioda--> 7<!--Adviser: @zengyawen--> 8 9将所支持格式的图片文件解码成[PixelMap](../../reference/apis-image-kit/arkts-apis-image-PixelMap.md),以便在应用或系统中显示或处理图片。当前支持的图片文件格式包括JPEG、PNG、GIF、WebP、BMP、SVG、ICO、DNG、HEIF。不同硬件设备的支持情况可能不同 。 10 11## 开发步骤 12 13图片解码相关API的详细介绍请参见:[图片解码接口说明](../../reference/apis-image-kit/arkts-apis-image-ImageSource.md)。 14 151. 全局导入Image模块。 16 17 ```ts 18 import { image } from '@kit.ImageKit'; 19 ``` 20 212. 获取图片。 22 - 方法一:通过沙箱路径直接获取。该方法仅适用于应用沙箱中的图片。更多细节请参考[获取应用文件路径](../../application-models/application-context-stage.md#获取应用文件路径)。应用沙箱的介绍及如何向应用沙箱推送文件,请参考[文件管理](../../file-management/app-sandbox-directory.md)。 23 24 ```ts 25 function getFilePath(context: Context): string { 26 const filePath: string = context.cacheDir + '/test.jpg'; 27 return filePath; 28 } 29 ``` 30 31 - 方法二:通过沙箱路径获取图片的文件描述符。具体请参考[file.fs API参考文档](../../reference/apis-core-file-kit/js-apis-file-fs.md)。该方法需要导入\@kit.CoreFileKit模块。 32 33 ```ts 34 import { fileIo as fs } from '@kit.CoreFileKit'; 35 36 function getFileFd(context: Context): number | undefined { 37 const filePath: string = context.cacheDir + '/test.jpg'; 38 const file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_WRITE); 39 const fd: number = file?.fd; 40 return fd; 41 } 42 ``` 43 44 - 方法三:通过资源管理器获取资源文件的ArrayBuffer。具体请参考[资源管理器API参考文档](../../reference/apis-localization-kit/js-apis-resource-manager.md#getrawfilecontent9-1)。该方法需要导入\@kit.LocalizationKit模块。 45 46 ```ts 47 import { resourceManager } from '@kit.LocalizationKit'; 48 49 async function getFileBuffer(context: Context): Promise<ArrayBuffer | undefined> { 50 try { 51 const resourceMgr: resourceManager.ResourceManager = context.resourceManager; 52 // 获取资源文件内容,返回Uint8Array。 53 const fileData: Uint8Array = await resourceMgr.getRawFileContent('test.jpg'); 54 console.info('Successfully got RawFileContent'); 55 // 转为ArrayBuffer并返回。 56 const buffer: ArrayBuffer = fileData.buffer.slice(0); 57 return buffer; 58 } catch (error) { 59 console.error("Failed to get RawFileContent"); 60 return undefined; 61 } 62 } 63 ``` 64 65 - 方法四:通过资源管理器获取资源文件的RawFileDescriptor。具体请参考[资源管理器API参考文档](../../reference/apis-localization-kit/js-apis-resource-manager.md#getrawfd9-1)。该方法需要导入\@kit.LocalizationKit模块。 66 ```ts 67 import { resourceManager } from '@kit.LocalizationKit'; 68 69 async function getRawFd(context: Context): Promise<resourceManager.RawFileDescriptor | undefined> { 70 try { 71 const resourceMgr: resourceManager.ResourceManager = context.resourceManager; 72 const rawFileDescriptor: resourceManager.RawFileDescriptor = await resourceMgr.getRawFd('test.jpg'); 73 console.info('Successfully got RawFileDescriptor'); 74 return rawFileDescriptor; 75 } catch (error) { 76 console.error('Failed to get RawFileDescriptor:'); 77 return undefined; 78 } 79 } 80 ``` 81 823. 创建ImageSource实例。 83 84 - 方法一:通过沙箱路径创建ImageSource。沙箱路径可以通过步骤2的方法一获取。 85 86 ```ts 87 // path为已获得的沙箱路径。 88 const imageSource : image.ImageSource = image.createImageSource(filePath); 89 ``` 90 91 - 方法二:通过文件描述符fd创建ImageSource。文件描述符可以通过步骤2的方法二获取。 92 93 ```ts 94 // fd为已获得的文件描述符。 95 const imageSource : image.ImageSource = image.createImageSource(fd); 96 ``` 97 98 - 方法三:通过缓冲区数组创建ImageSource。缓冲区数组可以通过步骤2的方法三获取。 99 100 ```ts 101 const imageSource : image.ImageSource = image.createImageSource(buffer); 102 ``` 103 104 - 方法四:通过资源文件的RawFileDescriptor创建ImageSource。RawFileDescriptor可以通过步骤2的方法四获取。 105 106 ```ts 107 const imageSource : image.ImageSource = image.createImageSource(rawFileDescriptor); 108 ``` 109 1104. 设置解码参数DecodingOptions,解码获取pixelMap图片对象。 111 - 设置期望的format进行解码: 112 ```ts 113 import { BusinessError } from '@kit.BasicServicesKit'; 114 import { image } from '@kit.ImageKit'; 115 116 // 创建ImageSource,请选择3中合适的方法替换。 117 let fd : number = 0; 118 let imageSource : image.ImageSource = image.createImageSource(fd); 119 // 配置解码选项参数。 120 let decodingOptions : image.DecodingOptions = { 121 editable: true, 122 desiredPixelFormat: image.PixelMapFormat.RGBA_8888, 123 }; 124 // 创建pixelMap。 125 imageSource.createPixelMap(decodingOptions).then((pixelMap : image.PixelMap) => { 126 console.info("Succeeded in creating PixelMap"); 127 }).catch((err : BusinessError) => { 128 console.error("Failed to create PixelMap"); 129 }); 130 ``` 131 - HDR图片解码 132 ```ts 133 import { BusinessError } from '@kit.BasicServicesKit'; 134 import { image } from '@kit.ImageKit'; 135 136 // 创建ImageSource,请选择3中合适的方法替换。 137 let fd : number = 0; 138 let imageSource : image.ImageSource = image.createImageSource(fd); 139 // 配置解码选项参数。 140 let decodingOptions : image.DecodingOptions = { 141 //设置为AUTO会根据图片资源格式解码,如果图片资源为HDR资源则会解码为HDR的pixelMap。 142 desiredDynamicRange: image.DecodingDynamicRange.AUTO, 143 }; 144 // 创建pixelMap。 145 imageSource.createPixelMap(decodingOptions).then((pixelMap : image.PixelMap) => { 146 console.info("Succeeded in creating PixelMap"); 147 // 判断pixelMap是否为hdr内容。 148 let info = pixelMap.getImageInfoSync(); 149 console.info("pixelMap isHdr:" + info.isHdr); 150 }).catch((err : BusinessError) => { 151 console.error("Failed to create PixelMap"); 152 }); 153 ``` 154 解码完成,获取到pixelMap对象后,可以进行后续[图片处理](image-transformation.md)。 155 1565. 释放pixelMap和imageSource。 157 158 确认pixelMap和imageSource的异步方法已经执行完成,不再使用该变量后,可按需手动调用下面方法释放。 159 ```ts 160 // 请务必在确认pixelMap不需要再使用时,再进行释放。 161 // pixelMap.release(); 162 // 请务必在确认imageSource不需要再使用时,再进行释放。 163 // imageSource.release(); 164 ``` 165 166 > **补充说明:** 167 > 1. 释放imageSource的合适时机:createPixelMap执行完成,成功获取pixelMap后,如果确定不再使用imageSource的其他方法,可以手动释放imageSource。由于解码得到的pixelMap是一个独立的实例,imageSource的释放不会导致pixelMap不可用。 168 > 2. 释放pixelMap的合适时机:如果使用系统的[Image组件](../../reference/apis-arkui/arkui-ts/ts-basic-components-image.md)进行图片显示,无需手动释放,Image组件会自动管理传递给它的pixelMap;如果应用自行处理pixelMap,则推荐在页面切换、应用退后台等场景下手动释放老页面pixelMap;在内存资源紧张的场景,推荐释放除当前页面外其他不可见页面的PixelMap。 169 170## 相关实例 171 172针对图片解码开发,有以下相关实例可供参考: 173 174- [图片编辑(ArkTS)](https://gitee.com/openharmony/codelabs/tree/master/Media/ImageEdit) 175 176- [图片编辑(JS)](https://gitee.com/openharmony/codelabs/tree/master/Media/ImageEditorTemplate) 177 178<!--RP1--> 179<!--RP1End-->