【鸿蒙开发】第十九章 Image图片处理

1 简介

应用开发中的图片开发是对图片像素数据进行解析处理构造的过程,达到目标图片效果,主要涉及图片解码图片处理图片编码等。

  • 图片解码
    指将所支持格式的存档图片解码成统一的PixelMap,以便在应用或系统中进行图片显示或图片处理。当前支持的存档图片格式包括JPEGPNGGIFRAWWebPBMPSVGICO

  • PixelMap
    指图片解码后无压缩的位图,用于图片显示或图片处理。

  • 图片处理
    指对PixelMap进行相关的操作,如旋转、缩放、设置透明度、获取图片信息、读写像素数据等。

  • 图片编码
    指将PixelMap编码成不同格式的存档图片(当前仅支持JPEGWebPPNG),用于后续处理,如保存、传输等。

在这里插入图片描述

  1. 获取图片:通过应用沙箱等方式获取原始图片。
  2. 创建ImageSource实例:ImageSource是图片解码出来的图片源类,用于获取或修改图片相关信息。
  3. 图片解码:通过ImageSource解码生成PixelMap
  4. 图片处理:对PixelMap进行处理,更改图片属性实现图片的旋转、缩放、裁剪等效果。然后通过Image组件显示图片。
  5. 图片编码:使用图片打包器类ImagePacker,将PixelMapImageSource进行压缩编码,生成一张新的图片。

除上述基本图片开发能力外,OpenHarmony还提供常用图片工具,供开发者选择使用。编解码支持多种图片格式,并采用了高效的算法和优化策略,提高了图片处理的速度和效率。在图片处理中,可能需要使用用户图片,应用需要向用户申请对应的读写操作权限才能保证功能的正常运行。图片框架提供图片编解码能力,为Image组件及图库等应用提供支撑,其解码结果可以传给Image组件显示。

下面我们来学习ArkTS相关的图片解码、编码。

2 图片解码(ArkTS)

图片解码指将所支持格式的存档图片解码成统一的PixelMap,以便在应用或系统中进行图片显示或图片处理。当前支持的存档图片格式包括JPEGPNGGIFRAWWebPBMPSVGICO

2.1 开发步骤

  1. 全局导入Image模块
import image from '@ohos.multimedia.image';
  1. 获取图片
  • 方法一:获取沙箱路径。具体请参考获取应用文件路径。应用沙箱的介绍及如何向应用沙箱推送文件,请参考文件管理。
// 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")// 获取图片的ArrayBufferconst 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")
});
  1. 创建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创建ImageSourceRawFileDescriptor可以通过步骤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")// 获取图片的ArrayBufferconst 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编码成不同格式的存档图片(当前仅支持打包为JPEGWebPpng 格式),用于后续处理,如保存、传输等。

3.1 图片编码进文件流

  1. 创建图像编码ImagePacker对象。
// 导入相关模块包
import image from '@ohos.multimedia.image';const imagePackerApi = image.createImagePacker();
  1. 设置编码输出流和编码参数。format为图像的编码格式;quality为图像质量,范围从0-100,100为最佳质量。
let packOpts : image.PackingOption = { format:"image/jpeg", quality:98 };
  1. 创建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信息的查看和修改

  1. 获取图片,创建图片源ImageSource
// 导入相关模块包
import image from '@ohos.multimedia.image';// 获取沙箱路径创建ImageSource
const fd : number = ...; // 获取需要被处理的图片的fd
const imageSource : image.ImageSource = image.createImageSource(fd);
  1. 读取、编辑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应用开发文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/600588.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Springboot高校学生饮食推荐系统的设计与实现(论文+源码)_kaic

摘 要 随着网络科技的不断发展以及人们经济水平的逐步提高,计算机如今已成为人们生活中不可缺少的一部分,为饮食分享轻松便捷的管理信息,基于java技术的饮食分享的设计与实现了一款简洁、轻便的管理系统。本系统解决了饮食分享管理事务中的主…

Ethernet 汇总

Ethernet系统 硬件最小系统 CPU:可以是复杂的芯片,也可以是小的单片机DMA:用于减轻CPU负担,搬运数据系统Memory<->FIFOMAC:可以集成在芯片里面,用于CPU和PHY之间的通信MII:接口用于MAC和PHY的通信,包括控制MDIO和数据DataPHY:模拟器件,最底层,数据收发源头软件…

记一次Cannot deploy POJO class [xxx$$EnhancerBySpringCGLIB$$xxx]的错误

最近项目上需要使用websocket做服务端&#xff0c;那好说啊&#xff0c;直接springboot集成的websocket 引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><versi…

【超简单】基于PaddleSpeech搭建个人语音听写服务

一、【超简单】之基于PaddleSpeech搭建个人语音听写服务 1.需求分析 亲们,你们要写会议纪要嘛?亲们,你们要写会议纪要嘛?亲们,你们要写会议纪要嘛?当您面对成吨的会议录音,着急写会议纪要而不得不愚公移山、人海战术?听的头晕眼花,听的漏洞百出,听的怀疑人生,那么你…

与汇智知了堂共舞,HW行动开启你的网络安全新篇章!

**网安圈内一年一度的HW行动来啦&#xff01; ** 招募对象 不限&#xff0c;有HW项目经验 或持有NISP二级、CISP证书优先 HW时间 以官方正式通知为准 工作地点&#xff1a;全国 薪资待遇 带薪HW &#xff08;根据考核成绩500-4000元/天不等&#xff09; 招募流程 1.填写报名…

静态代理

静态代理 静态代理 理解示例 角色分析: 抽象角色:一般会使用接口或者抽象类类解决 真实角色:被代理的角色 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作 客户:访问代理对象的人 分析: 抽象角色 真实角色 代理角色(代理真实的对象) 客户 …

GPT-4对多模态大模型在多模态预训练、 理解生成上的启发

传统人工智能 模型往往依赖大量有标签数据的监督训练,而且一个模型一般只能解决一个任务,仅适用于单一场景, 这使得人工智能的研发和应用成本高,场景适应能力弱,难以规模化应用。 常见的多模态任务大致可以分为两类: 多模态理解任务,如视频 分类、视觉问答、跨模态检索、指代…

Echarts-实现地图并轮播地图信息

目录 ./map-geojson/jinhua.json./CenterMap.vue./center.vue 使用地图组件效果 ./map-geojson/jinhua.json {"type":"FeatureCollection","features":[{"type":"Feature","properties":{"adcode":330…

DHT11温度检测系统

DHT11温湿度传感器 产品概述 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器&#xff0c;应用领域&#xff1a;暖通空调&#xff1b;汽车&#xff1b;消费品&#xff1b;气象站&#xff1b;湿度调节器&#xff1b;除湿器&#xff1b;家电&#xff1b;医…

Android 11 上的文件读写无权限问题

Android 6以上需要动态申请读写权限&#xff0c;但是11以上动态申请了读写权限也是无效。并且手动给予权限没有该按钮。 如上图华为钱包有个所有文件权限、但是百度地图只有仅媒体权限&#xff0c;仅媒体权限&#xff08;动态申请读写权限&#xff09;给予后软件还是没法访问文…

飞书文档如何在不同账号间迁移

今天由于个人需要新建了一个飞书账号&#xff0c;遇到个需求就是需要把老帐号里面的文档迁移到新的账号里面。在网上搜了一通&#xff0c;发现关于此的内容似乎不多&#xff0c;只好自己动手解决&#xff0c;记录一下过程以便分享&#xff0c;主要有以下几个步骤。 1. 添加新账…

【Vue】实现仿微信输入@出现选择框

<div style"padding: 10px 10px" class"editor"><el-inputresizetype"textarea":rows"4"clearableplaceholder"请输入您的问题.."v-model"requestParams.prompt"input"handleInput"keydown.na…