1 简介
应用开发中的图片开发是对图片像素数据进行解析、处理、构造的过程,达到目标图片效果,主要涉及图片解码、图片处理、图片编码等。
-
图片解码
指将所支持格式的存档图片解码成统一的PixelMap,以便在应用或系统中进行图片显示或图片处理。当前支持的存档图片格式包括JPEG、PNG、GIF、RAW、WebP、BMP、SVG、ICO。 -
PixelMap
指图片解码后无压缩的位图,用于图片显示或图片处理。 -
图片处理
指对PixelMap进行相关的操作,如旋转、缩放、设置透明度、获取图片信息、读写像素数据等。 -
图片编码
指将PixelMap编码成不同格式的存档图片(当前仅支持JPEG、WebP和PNG),用于后续处理,如保存、传输等。

- 获取图片:通过应用沙箱等方式获取原始图片。
- 创建
ImageSource实例:ImageSource是图片解码出来的图片源类,用于获取或修改图片相关信息。 - 图片解码:通过
ImageSource解码生成PixelMap。 - 图片处理:对
PixelMap进行处理,更改图片属性实现图片的旋转、缩放、裁剪等效果。然后通过Image组件显示图片。 - 图片编码:使用图片打包器类
ImagePacker,将PixelMap或ImageSource进行压缩编码,生成一张新的图片。
除上述基本图片开发能力外,OpenHarmony还提供常用图片工具,供开发者选择使用。编解码支持多种图片格式,并采用了高效的算法和优化策略,提高了图片处理的速度和效率。在图片处理中,可能需要使用用户图片,应用需要向用户申请对应的读写操作权限才能保证功能的正常运行。图片框架提供图片编解码能力,为Image组件及图库等应用提供支撑,其解码结果可以传给Image组件显示。
下面我们来学习ArkTS相关的图片解码、编码。
2 图片解码(ArkTS)
图片解码指将所支持格式的存档图片解码成统一的PixelMap,以便在应用或系统中进行图片显示或图片处理。当前支持的存档图片格式包括JPEG、PNG、GIF、RAW、WebP、BMP、SVG、ICO。
2.1 开发步骤
- 全局导入
Image模块
import image from '@ohos.multimedia.image';
- 获取图片
- 方法一:获取沙箱路径。具体请参考获取应用文件路径。应用沙箱的介绍及如何向应用沙箱推送文件,请参考文件管理。
// Stage模型参考如下代码
const context : Context = getContext(this);
const filePath : string = context.cacheDir + '/test.jpg';
// FA模型参考如下代码
import featureAbility from '@ohos.ability.featureAbility';
const context = featureAbility.getContext();
const filePath = context.getCacheDir() + "/test.jpg";
- 方法二:通过沙箱路径获取图片的文件描述符。具体请参考
file.fs API参考文档。 该方法需要先导入@ohos.file.fs模块。
import fs from '@ohos.file.fs';
然后调用fs.openSync()获取文件描述符。
// Stage模型参考如下代码
const context = getContext(this);
const filePath = context.cacheDir + '/test.jpg';
const file : fs.File = fs.openSync(filePath, fs.OpenMode.READ_WRITE);
const fd : number = file?.fd;
// FA模型参考如下代码
import featureAbility from '@ohos.ability.featureAbility';
const context = featureAbility.getContext();
const filePath = context.getCacheDir() + "/test.jpg";
const file : fs.File = fs.openSync(filePath, fs.OpenMode.READ_WRITE);
const fd : number = file?.fd;
- 方法三:通过资源管理器获取资源文件的
ArrayBuffer。
// Stage模型
const context : Context = getContext(this);
// 获取resourceManager资源管理器
const resourceMgr : resourceManager.ResourceManager = context.resourceManager;
// FA模型
// 导入resourceManager资源管理器
import resourceManager from '@ohos.resourceManager';
import {BusinessError} from '@ohos.base';
resourceManager.getResourceManager().then((resourceMgr : resourceManager.ResourceManager) => {
console.log("Succeeded in getting resourceManager")
}).catch((err : BusinessError) => {
console.error("Failed to get resourceManager")
});
不同模型获取资源管理器的方式不同,获取资源管理器后,再调用resourceMgr.getRawFileContent()获取资源文件的ArrayBuffer。
resourceMgr.getRawFileContent('test.jpg').then((fileData : Uint8Array) => {
console.log("Succeeded in getting RawFileContent")
// 获取图片的ArrayBuffer
const buffer = fileData.buffer.slice(0);
}).catch((err : BusinessError) => {
console.error("Failed to get RawFileContent")
});
- 方法四:通过资源管理器获取资源文件的
RawFileDescriptor。
// Stage模型
const context : Context = getContext(this);
// 获取resourceManager资源管理器
const resourceMgr : resourceManager.ResourceManager = context.resourceManager;
// FA模型
// 导入resourceManager资源管理器
import resourceManager from '@ohos.resourceManager';
import {BusinessError} from '@ohos.base';
resourceManager.getResourceManager().then((resourceMgr : resourceManager.ResourceManager) => {
console.log("Succeeded in getting resourceManager")
}).catch((err : BusinessError) => {
console.error("Failed to get resourceManager")
});
不同模型获取资源管理器的方式不同,获取资源管理器后,再调用resourceMgr.getRawFd()获取资源文件的RawFileDescriptor。
resourceMgr.getRawFd('test.jpg').then((rawFileDescriptor : resourceManager.RawFileDescriptor) => {
console.log("Succeeded in getting resourceManager")
}).catch((err : BusinessError) => {
console.error("Failed to get resourceManager")
});
- 创建
ImageSource实例。
- 方法一:通过沙箱路径创建
ImageSource。沙箱路径可以通过步骤2的方法一获取。
// path为已获得的沙箱路径
const imageSource : image.ImageSource = image.createImageSource(filePath);
- 方法二:通过文件描述符
fd创建ImageSource。文件描述符可以通过步骤2的方法二获取。
// fd为已获得的文件描述符
const imageSource : image.ImageSource = image.createImageSource(fd);
- 方法三:通过缓冲区数组创建
ImageSource。缓冲区数组可以通过步骤2的方法三获取。
const imageSource : image.ImageSource = image.createImageSource(buffer);
- 方法四:通过资源文件的
RawFileDescriptor创建ImageSource。RawFileDescriptor可以通过步骤2的方案四获取。
const imageSource : image.ImageSource = image.createImageSource(rawFileDescriptor);
设置解码参数DecodingOptions,解码获取PixelMap图片对象。
import {BusinessError} from '@ohos.base';
let decodingOptions : image.DecodingOptions = {
editable: true,
desiredPixelFormat: 3,
}
// 创建pixelMap并进行简单的旋转和缩放
imageSource.createPixelMap(decodingOptions).then((pixelMap : image.PixelMap) => {
console.log("Succeeded in creating PixelMap")
}).catch((err : BusinessError) => {
console.error("Failed to create PixelMap")
});
解码完成,获取到PixelMap对象后,可以进行后续图片处理。释放pixelMap。
pixelMap.release();
2.2 示例
// 1. 获取resourceManager资源管理
const context : Context = getContext(this);
const resourceMgr : resourceManager.ResourceManager = context.resourceManager;
// 2. 创建ImageSource。
// 通过rawfile文件夹下test.jpg的ArrayBuffer创建。
resourceMgr.getRawFileContent('test.jpg').then((fileData : Uint8Array) => {
console.log("Succeeded in getting RawFileContent")
// 获取图片的ArrayBuffer
const buffer = fileData.buffer.slice(0);
const imageSource : image.ImageSource = image.createImageSource(buffer);
}).catch((err : BusinessError) => {
console.error("Failed to get RawFileContent")
});
// 通过rawfile文件夹下test.jpg的RawFileDescriptor创建。
resourceMgr.getRawFd('test.jpg').then((rawFileDescriptor : resourceManager.RawFileDescriptor) => {
console.log("Succeeded in getting RawFd")
const imageSource : image.ImageSource = image.createImageSource(rawFileDescriptor);
}).catch((err : BusinessError) => {
console.error("Failed to get RawFd")
});
// 3. 创建PixelMap。
imageSource.createPixelMap().then((pixelMap: image.PixelMap) => {
console.log("Succeeded in creating PixelMap")
}).catch((err : BusinessError) => {
console.error("Failed to creating PixelMap")
});
// 4. 释放pixelMap。
pixelMap.release();
3 图片编码(ArkTS)
图片编码指将PixelMap编码成不同格式的存档图片(当前仅支持打包为JPEG、WebP和 png 格式),用于后续处理,如保存、传输等。
3.1 图片编码进文件流
- 创建图像编码
ImagePacker对象。
// 导入相关模块包
import image from '@ohos.multimedia.image';
const imagePackerApi = image.createImagePacker();
- 设置编码输出流和编码参数。
format为图像的编码格式;quality为图像质量,范围从0-100,100为最佳质量。
let packOpts : image.PackingOption = { format:"image/jpeg", quality:98 };
- 创建
PixelMap对象或创建ImageSource对象。进行图片编码,并保存编码后的图片。
- 方法一:通过
PixelMap进行编码。
import {BusinessError} from '@ohos.base'
imagePackerApi.packing(pixelMap, packOpts).then( (data : ArrayBuffer) => {
// data 为打包获取到的文件流,写入文件保存即可得到一张图片
}).catch((error : BusinessError) => {
console.error('Failed to pack the image. And the error is: ' + error);
})
- 方法二:通过
imageSource进行编码。
import {BusinessError} from '@ohos.base'
imagePackerApi.packing(imageSource, packOpts).then( (data : ArrayBuffer) => {
// data 为打包获取到的文件流,写入文件保存即可得到一张图片
}).catch((error : BusinessError) => {
console.error('Failed to pack the image. And the error is: ' + error);
})
3.2 图片编码进文件
在编码时,开发者可以传入对应的文件路径,编码后的内存数据将直接写入文件。
- 方法一:通过
PixelMap编码进文件。
import {BusinessError} from '@ohos.base'
import fs from '@ohos.file.fs'
const context : Context = getContext(this);
const path : string = context.cacheDir + "/pixel_map.jpg";
let file = fs.openSync(path, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
imagePackerApi.packToFile(pixelMap, file.fd, packOpts).then(() => {
// 直接打包进文件
}).catch((error : BusinessError) => {
console.error('Failed to pack the image. And the error is: ' + error);
})
- 方法二:通过
imageSource编码进文件。
import {BusinessError} from '@ohos.base'
import fs from '@ohos.file.fs'
const context : Context = getContext(this);
const filePath : string = context.cacheDir + "/image_source.jpg";
let file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
imagePackerApi.packToFile(imageSource, file.fd, packOpts).then(() => {
// 直接打包进文件
}).catch((error : BusinessError) => {
console.error('Failed to pack the image. And the error is: ' + error);
})
4 图片工具
图片工具当前主要提供图片EXIF信息的读取与编辑能力。
EXIF(Exchangeable image file format)是专门为数码相机的照片设定的文件格式,可以记录数码照片的属性信息和拍摄数据。当前仅支持JPEG格式图片。
在图库等应用中,需要查看或修改数码照片的EXIF信息。由于摄像机的手动镜头的参数无法自动写入到EXIF信息中或者因为相机断电等原因经常会导致拍摄时间出错,这时候就需要手动修改错误的EXIF数据,即可使用本功能。
OpenHarmony目前仅支持对部分EXIF信息的查看和修改
- 获取图片,创建图片源
ImageSource。
// 导入相关模块包
import image from '@ohos.multimedia.image';
// 获取沙箱路径创建ImageSource
const fd : number = ...; // 获取需要被处理的图片的fd
const imageSource : image.ImageSource = image.createImageSource(fd);
- 读取、编辑
EXIF信息。
import {BusinessError} from '@ohos.base';
// 读取EXIF信息,BitsPerSample为每个像素比特数
let options : image.ImagePropertyOptions = { index: 0, defaultValue: '9999' }
imageSourceApi.getImageProperty(image.PropertyKey.BITS_PER_SAMPLE, options).then((data : string) => {
console.log('Succeeded in getting the value of the specified attribute key of the image.');
}).catch((error : BusinessError) => {
console.error('Failed to get the value of the specified attribute key of the image.');
})
// 编辑EXIF信息
imageSourceApi.modifyImageProperty(image.PropertyKey.IMAGE_WIDTH, "120").then(() => {
imageSourceApi.getImageProperty(image.PropertyKey.IMAGE_WIDTH).then((width : string) => {
console.info('The new imageWidth is ' + width);
}).catch((error : BusinessError) => {
console.error('Failed to get the Image Width.');
})
}).catch((error : BusinessError) => {
console.error('Failed to modify the Image Width');
})
参考文献:
[1]OpenHarmoney应用开发文档

935

被折叠的 条评论
为什么被折叠?



