• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-->