本文同步发表于微信公众号微信搜索程语新视界即可关注每个工作日都有文章更新在上一篇文章中介绍了Image Kit的整体能力。今天来聊聊其中的核心功能——使用ImageSource完成图片解码。图片解码是将图片文件转换成PixelMap位图对象的过程是图片显示和处理的基础。一、图片解码将所支持格式的图片文件解码成PixelMap位图对象以便在应用或系统中显示或处理图片。支持的图片格式格式说明JPEG常见图片格式PNG支持透明通道GIF支持动图WebPGoogle推出的现代图片格式BMP位图格式SVG矢量图格式ICO图标格式DNG数码相机原始图像格式HEIC高效率图像文件格式注意不同硬件设备的支持情况可能不同。RAW格式预览图解码API 22从API version 22开始支持对专业相机拍摄的RAW格式图片内嵌的预览图通常为JPEG格式进行解码RAW格式文件扩展名CR2/CR3CanonARWSonyNEF/NRWNikonRAFFujifilmORFOlympusRW2PanasonicPEFPentaxSRWSamsung说明该解码能力不受运行设备类型限制。二、导入模块import { image } from kit.ImageKit; import { BusinessError } from kit.BasicServicesKit; import { common } from kit.AbilityKit; import { fileIo as fs } from kit.CoreFileKit; import { resourceManager } from kit.LocalizationKit;三、获取图片四种方式3.1 方式一通过沙箱路径直接获取适用于应用沙箱中的图片。function getFilePath(context: Context, fileName: string): string { const filePath: string context.cacheDir / fileName; return filePath; }3.2 方式二通过文件描述符fd获取通过沙箱路径获取图片的文件描述符。function getFileFd(context: Context, fileName: string): number | undefined { const filePath: string context.cacheDir / fileName; const file: fs.File fs.openSync(filePath, fs.OpenMode.READ_ONLY); const fd: number file?.fd; return fd; }3.3 方式三通过资源管理器获取ArrayBuffer通过资源管理器获取资源文件的ArrayBuffer。async function getFileBuffer(context: Context, fileName: string): PromiseArrayBuffer | undefined { try { const resourceMgr: resourceManager.ResourceManager context.resourceManager; // 获取资源文件内容返回Uint8Array const fileData: Uint8Array await resourceMgr.getRawFileContent(fileName); console.info(Successfully get the RawFileContent.); // 转为ArrayBuffer并返回 const buffer: ArrayBuffer fileData.buffer.slice(0); return buffer; } catch (error) { console.error(Failed to get the RawFileContent with error: ${error}.); return undefined; } }3.4 方式四通过资源管理器获取RawFileDescriptor通过资源管理器获取资源文件的RawFileDescriptor。async function getRawFd(context: Context, fileName: string): PromiseresourceManager.RawFileDescriptor | undefined { try { const resourceMgr: resourceManager.ResourceManager context.resourceManager; const rawFileDescriptor: resourceManager.RawFileDescriptor await resourceMgr.getRawFd(fileName); console.info(Successfully get the RawFileDescriptor.); return rawFileDescriptor; } catch (error) { console.error(Failed to get the RawFileDescriptor with error: ${error}.); return undefined; } }四、创建ImageSource实例创建方式数据来源方法方式一沙箱路径image.createImageSource(filePath)方式二文件描述符fdimage.createImageSource(fd)方式三缓冲区ArrayBufferimage.createImageSource(buffer)方式四RawFileDescriptorimage.createImageSource(rawFileDescriptor)4.1 通过沙箱路径创建// path为已获得的沙箱路径 const imageSource: image.ImageSource image.createImageSource(filePath);4.2 通过文件描述符fd创建// fd为已获得的文件描述符 const imageSource: image.ImageSource image.createImageSource(fd);4.3 通过缓冲区数组创建// buffer为已获得的ArrayBuffer const imageSource: image.ImageSource image.createImageSource(buffer);4.4 通过RawFileDescriptor创建// rawFileDescriptor为已获得的RawFileDescriptor const imageSource: image.ImageSource image.createImageSource(rawFileDescriptor);五、解码获取PixelMap5.1 DecodingOptions参数参数类型说明editableboolean是否可编辑desiredPixelFormatPixelMapFormat目标像素格式如RGBA_8888desiredDynamicRangeDecodingDynamicRange动态范围AUTO/HDR等5.2 解码代码示例async function createPixelMap(imageSource: image.ImageSource | undefined): Promiseimage.PixelMap | undefined { if (!imageSource) { console.error(imageSource is undefined.); return undefined; } // 配置解码选项参数 let decodingOptions: image.DecodingOptions { editable: true, // 可编辑 desiredPixelFormat: image.PixelMapFormat.RGBA_8888, // RGBA格式 // AUTO根据图片资源格式和设备支持情况进行解码 // 如果图片资源为HDR资源且设备支持HDR解码则会解码为HDR的pixelMap desiredDynamicRange: image.DecodingDynamicRange.HDR, }; try { // 生成 pixelMap 并返回 const pixelMap await imageSource.createPixelMap(decodingOptions); if (pixelMap) { console.info(Create PixelMap successfully.); // 判断pixelMap是否为hdr内容 let imageInfo await pixelMap.getImageInfo(); console.info(Create PixelMap successfully with imageInfo.isHdr: ${imageInfo.isHdr}.); return pixelMap; } else { console.info(Create PixelMap failed.); return undefined; } } catch (error) { console.error(Failed to create PixelMap: ${error}.); return undefined; } }六、释放资源6.1 释放时机资源释放时机ImageSourcecreatePixelMap执行完成成功获取pixelMap后如果确定不再使用imageSource的其他方法可以手动释放PixelMap页面切换、应用退后台、内存紧张时释放除当前页面外其他不可见页面的PixelMap6.2 释放代码async function release(pixelMap: image.PixelMap | undefined, imageSource: image.ImageSource | undefined) { pixelMap?.release(); pixelMap undefined; imageSource?.release(); imageSource undefined; }6.3 说明imageSource与pixelMap独立解码得到的pixelMap是一个独立的实例imageSource的释放不会导致pixelMap不可用Image组件自动管理如果使用系统的Image组件进行图片显示无需手动释放Image组件会自动管理传递给它的pixelMap手动释放场景应用自行处理pixelMap时推荐在页面切换、应用退后台等场景下手动释放流程获取图片数据 ↓ 创建ImageSource实例 ↓ 配置DecodingOptions解码参数 ↓ 调用createPixelMap解码 ↓ 获取PixelMap进行显示/处理 ↓ 释放资源imageSource、pixelMap鸿蒙图片解码通过ImageSource将图片文件转换为PixelMap位图对象支持四种数据来源沙箱路径、文件描述符、ArrayBuffer、RawFileDescriptor可通过DecodingOptions配置可编辑性、像素格式和动态范围解码后的PixelMap可用于Image组件显示或后续处理。