图像开发概述
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。
接口说明
ImageSource主要用于图像解码。
普通解码开发步骤
1. 创建图像数据源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);
2. 设置解码参数,解码获取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);
3. 解码完成获取到PixelMap对象后,可以进行后续处理,比如渲染显示等。
渐进式解码开发步骤
1. 创建渐进式图像数据源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 = ImageSource.createIncrementalSource(incOpts);
2. 渐进式更新数据。在未获取到全部图像时,支持先更新部分数据来尝试解码,调用updateData更新数据,将参数isFinal设置为false;当获取到全部数据后,最后一次更新数据时设置isFinal为true,表示数据更新完毕。设置解码参数同普通解码。
// 传入本地图片路径作为图像数据源 File file = new File("/sdcard/test.jpg"); FileInputStream fis = null; try { fis = new FileInputStream(file); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] data = new byte[1024]; int len = -1; while((len = fis.read(data)) != -1) { bos.write(data, 0, len); } byte[] fileByte = bos.toByteArray(); // 获取到一定的数据时尝试解码 imageSource.updateData(fileByte, 0, fileByte.length / 2, false); ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions(); PixelMap pixelMap = imageSource.createPixelmap(decodingOpts); // 更新数据再次解码,重复调用直到数据全部更新完成 imageSource.updateData(fileByte, fileByte.length / 2, fileByte.length / 4, false); pixelMap = imageSource.createPixelmap(decodingOpts); // 数据全部更新完成时需要传入isFinal为true imageSource.updateData(fileByte, fileByte.length * 3 / 4, fileByte.length / 4, true); pixelMap = imageSource.createPixelmap(decodingOpts); } catch (IOException e) { e.printStackTrace(); }