HarmonyOS之深入解析图像的编码和解码

一、基本概念
  • HarmonyOS 图像模块支持图像业务的开发,常见功能如图像解码、图像编码、基本的位图操作、图像编辑等。当然,也支持通过接口组合来实现更复杂的图像处理逻辑。
  • 图像解码:图像解码就是不同的存档格式图片(如 JPEG、PNG 等)解码为无压缩的位图格式,以方便在应用或者系统中进行相应的处理。
  • PixelMap:PixelMap 是图像解码后无压缩的位图格式,用于图像显示或者进一步的处理。
  • 渐进式解码:渐进式解码是在无法一次性提供完整图像文件数据的场景下,随着图像文件数据的逐步增加,通过多次增量解码逐步完成图像解码的模式。
  • 预乘:预乘时,RGB 各通道的值被替换为原始值乘以 Alpha 通道不透明的比例(0~1)后的值,方便后期直接合成叠加;不预乘指 RGB 各通道的数值是图像的原始值,与 Alpha 通道的值无关。
  • 图像编码:图像编码就是将无压缩的位图格式,编码成不同格式的存档格式图片( JPEG、PNG 等),以方便在应用或者系统中进行相应的处理。
  • 为及时释放本地资源,建议在图像解码的 ImageSource 对象、位图图像 PixelMap 对象或图像编码的 ImagePacker 对象使用完成后,主动调用 ImageSource、PixelMap 和 ImagePacker 的 release() 方法。
二、图像解码
① 应用场景
  • 图像解码就是将所支持格式的存档图片解码成统一的 PixelMap 图像,用于后续图像显示或其他处理,比如旋转、缩放、裁剪等。当前支持格式包括 JPEG、PNG、GIF、HEIF、WebP、BMP。
② 解码 API
  • mageSource 主要用于图像解码:
接口名描述
create(String pathName, SourceOptions opts)从图像文件路径创建图像数据源
create(InputStream is, SourceOptions opts)从输入流创建图像数据源
create(byte[] data, SourceOptions opts)从字节数组创建图像源
create(byte[] data, int offset, int length, SourceOptions opts)从字节数组指定范围创建图像源
create(File file, SourceOptions opts)从文件描述符创建图像数据源
create(FileDescriptor fd, SourceOptions opts)创建渐进式图像数据源
createIncrementalSource(SourceOptions opts)创建渐进式图像数据源,支持设置渐进式数据更新模式
createIncrementalSource(IncrementalSourceOptions opts)从图像数据源解码并创建PixelMap图像
createPixelmap(DecodingOptions opts)从图像数据源解码并创建PixelMap图像,如果图像数据源支持多张图片的话,支持指定图像索引
createPixelmap(int index, DecodingOptions opts)更新渐进式图像源数据
updateData(byte[] data, boolean isFinal)更新渐进式图像源数据,支持设置输入数据的有效数据范围
updateData(byte[] data, int offset, int length, boolean isFinal)更新渐进式图像源数据,支持设置输入数据的有效数据范围
getImageInfo()获取图像基本信息
getImageInfo(int index)根据特定的索引获取图像基本信息
getSourceInfo()获取图像源信息
release()释放对象关联的本地资源
③ 普通解码
  • 创建图像数据源 ImageSource 对象,可以通过 SourceOptions 指定数据源的格式信息,此格式信息仅为给解码器的提示,正确提供能帮助提高解码效率,如果不设置或设置不正确,会自动检测正确的图像格式。不使用该选项时,可以将 create 接口传入的 SourceOptions 设置为 null。
	ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
	srcOpts.formatHint = "image/png";
	String pathName = "/sdcard/image.png";
	ImageSource imageSource = ImageSource.create(pathName, srcOpts);
	// 不通过SourceOptions指定数据源格式信息
	ImageSource imageSourceNoOptions = ImageSource.create(pathName, null);
  • 设置解码参数,解码获取 PixelMap 图像对象,解码过程中同时支持图像处理操作。
    • 设置 desiredSize 支持按尺寸缩放,如果设置为全 0,则不进行缩放。
    • 设置 desiredRegion 支持按矩形区域裁剪,如果设置为全 0,则不进行裁剪。
    • 设置 rotateDegrees 支持旋转角度,以图像中心点顺时针旋转。
  • 如果只需要解码原始图像,不使用该选项时,可将给 createPixelMap 传入的 DecodingOptions 设置为 null。
	// 普通解码叠加缩放、裁剪、旋转
	ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
	decodingOpts.desiredSize = new Size(100, 2000);
	decodingOpts.desiredRegion = new Rect(0, 0, 100, 100);
	decodingOpts.rotateDegrees = 90;
	PixelMap pixelMap = imageSource.createPixelmap(decodingOpts); 
	// 普通解码
	PixelMap pixelMapNoOptions = imageSource.createPixelmap(null);
  • 解码完成获取到 PixelMap 对象后,可以进行后续处理,比如渲染显示等。
④ 渐进式解码
  • 创建渐进式图像数据源 ImageSource 对象:可以通过 SourceOptions 指定数据源的格式信息,此格式信息仅为提示,如果填写不正确,会自动检测正确的图像格式。使用 IncrementalSourceOptions 指定图像数据的更新方式为渐进式更新。
	ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
	srcOpts.formatHint = "image/jpeg";
	ImageSource.IncrementalSourceOptions incOpts = new ImageSource.IncrementalSourceOptions();
	incOpts.opts = srcOpts;
	incOpts.mode = ImageSource.UpdateMode.INCREMENTAL_DATA;
	imageSource = ImageSource.createIncrementalSource(incOpts);
  • 渐进式更新数据,在未获取到全部图像时,支持先更新部分数据来尝试解码,调用 updateData 更新数据,将参数 isFinal 设置为 false;当获取到全部数据后,最后一次更新数据时设置 isFinal为true,表示数据更新完毕,设置解码参数同普通解码。
	// 获取到一定的数据时尝试解码
	imageSource.updateData(data, 0, bytes, false);
	ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
	PixelMap pixelMap = imageSource.createPixelmap(decodingOpts);
	
	// 更新数据再次解码,重复调用直到数据全部更新完成
	imageSource.updateData(data, 0, bytes, false);
	PixelMap pixelMap = imageSource.createPixelmap(decodingOpts);
	
	// 数据全部更新完成时需要传入isFinal为true
	imageSource.updateData(data, 0, bytes, true);
	PixelMap pixelMap = imageSource.createPixelmap(decodingOpts);
  • 解码完成获取到 PixelMap 对象后,可以进行后续处理,比如渲染显示等。
三、图像编码
① 应用场景
  • 图像编码就是将 PixelMap 图像编码成不同存档格式图片,用于后续其他处理,比如保存、传输等。当前仅支持 JPEG 格式。
② 编码 API
  • ImagePacker 主要用于图像编码:
接口名描述
create()创建图像打包器实例
initializePacking(byte[] data, PackingOptions opts)初始化打包任务,将字节数组设置为打包后输出目的
initializePacking(byte[] data, int offset, PackingOptions opts)初始化打包任务,将带偏移量的字节数组设置为打包后输出目的
initializePacking(OutputStream outputStream, PackingOptions opts)初始化打包任务,将输出流设置为打包后输出目的
addImage(PixelMap pixelmap)将PixelMap对象添加到图像打包器中
addImage(ImageSource source)将图像数据源ImageSource中图像添加到图像打包器中
addImage(ImageSource source, int index)将图像数据源ImageSource中指定图像添加到图像打包器中
finalizePacking()完成图像打包任务
release()释放对象关联的本地资源
③ 图像编码流程
  • 创建图像编码 ImagePacker 对象:
	ImagePacker imagePacker = ImagePacker.create();
  • 设置编码输出流和编码参数。设置 format 为编码的图像格式,当前支持 jpeg 格式。设置 quality 为图像质量,范围从0-100,100为最佳质量。
	FileOutputStream outputStream = new FileOutputStream("/path/to/packed.file");
	ImagePacker.PackingOptions packingOptions = new ImagePacker.PackingOptions();
	packingOptions.format = "image/jpeg";
	packingOptions.quality = 90;
	boolean result = imagePacker.initializePacking(outputStream, packingOptions);
  • 添加需要编码的 PixelMap 对象,进行编码操作。
	result = imagePacker.addImage(myPixelMap);
	long dataSize = imagePacker.finalizePacking();
  • 编码输出完成后,可以进行后续处理,比如保存、传输等。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

╰つ栺尖篴夢ゞ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值