鸿蒙 ImageSource图片解码:转换成PixelMap
·
本文同步发表于微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
在上一篇文章中介绍了Image Kit的整体能力。今天来聊聊其中的核心功能——使用ImageSource完成图片解码。
图片解码是将图片文件转换成PixelMap位图对象的过程,是图片显示和处理的基础。
一、图片解码
将所支持格式的图片文件解码成PixelMap(位图对象),以便在应用或系统中显示或处理图片。
支持的图片格式
| 格式 | 说明 |
|---|---|
| JPEG | 常见图片格式 |
| PNG | 支持透明通道 |
| GIF | 支持动图 |
| WebP | Google推出的现代图片格式 |
| BMP | 位图格式 |
| SVG | 矢量图格式 |
| ICO | 图标格式 |
| DNG | 数码相机原始图像格式 |
| HEIC | 高效率图像文件格式 |
注意:不同硬件设备的支持情况可能不同。
RAW格式预览图解码(API 22+)
从API version 22开始,支持对专业相机拍摄的RAW格式图片内嵌的预览图(通常为JPEG格式)进行解码:
| RAW格式 | 文件扩展名 |
|---|---|
| CR2/CR3 | Canon |
| ARW | Sony |
| NEF/NRW | Nikon |
| RAF | Fujifilm |
| ORF | Olympus |
| RW2 | Panasonic |
| PEF | Pentax |
| SRW | Samsung |
说明:该解码能力不受运行设备类型限制。
二、导入模块
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): Promise<ArrayBuffer | 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): Promise<resourceManager.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) |
| 方式二 | 文件描述符fd | image.createImageSource(fd) |
| 方式三 | 缓冲区ArrayBuffer | image.createImageSource(buffer) |
| 方式四 | RawFileDescriptor | image.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);
五、解码获取PixelMap
5.1 DecodingOptions参数
| 参数 | 类型 | 说明 |
|---|---|---|
editable |
boolean | 是否可编辑 |
desiredPixelFormat |
PixelMapFormat | 目标像素格式(如RGBA_8888) |
desiredDynamicRange |
DecodingDynamicRange | 动态范围(AUTO/HDR等) |
5.2 解码代码示例
async function createPixelMap(imageSource: image.ImageSource | undefined): Promise<image.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 释放时机
| 资源 | 释放时机 |
|---|---|
| ImageSource | createPixelMap执行完成,成功获取pixelMap后,如果确定不再使用imageSource的其他方法,可以手动释放 |
| PixelMap | 页面切换、应用退后台、内存紧张时释放除当前页面外其他不可见页面的PixelMap |
6.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组件显示或后续处理。
更多推荐


所有评论(0)