当前位置: 首页 > news >正文

鸿蒙NEXT开发笔记(十三)仿微信聊天App的BASE64转像素图

上一节我们综合使用fileIo、image、buffer等工具库,把图片文件的二进制数据成功编码为BASE64字符串。那么为了能够正常收发图片消息,还需从BASE64字符串解码得到原始的图片数据,这样一来一去的无损逆向操作,方能实现准确无误的图片传输功能。
对于鸿蒙App来说,由于Image组件可直接显示PixelMap像素图,因此BASE64串无需转成图片文件,只需转到PixelMap这步即可。由BASE64串转像素图的具体过程包含以下三个步骤。

一、把BASE64字符串解码为二进制数据

对于BASE64字符串的解码操作,需要引入工具库util,也就是在ETS代码开头添加下面的导包语句:

import { util } from '@kit.ArkTS';

接着声明一个字节数组变量,用于保存BASE64解码后的二进制数据,鸿蒙系统的字节数组类型为Uint8Array。下面是字节数组变量的声明代码:

private resultUint8: Uint8Array | null = null;

然后通过util库把BASE64解码后的二进制数据存入上面的字节数组,具体的解码步骤说明如下:
1、先调用util.Base64Helper的构造方法,创建BASE64的帮助器对象;
2、再调用帮助器对象的decodeSync方法,从指定的BASE64字符串解码获得ArrayBuffer类型的缓存数据;
3、因为图片数据可能分段传输,所以要调用字节数组的set方法,在指定的起始位置分别写入前面解码得到的二进制数据;
详细的BASE64字符串还原代码如下:

// 把接收到的图片数据通过BASE64解码为字节数组
let helper = new util.Base64Helper();
let temp = helper.decodeSync(base64, util.Type.MIME).buffer as ArrayBuffer;
this.resultUint8?.set(new Uint8Array(temp), seq*this.blockSize)

二、抽取二进制数据的数组缓存

循环执行上面第一步的解码操作,直到所有的图片分段数据都解码并写入字节数组,再把该字节数组的buffer字段转换为ArrayBuffer类型的缓存数据。
下面是从字节数组获取缓存数据的代码:

let totalBuffer = this.resultUint8?.buffer as ArrayBuffer

三、把缓存数据还原为像素图

缓存数据转像素图属于图像处理操作,需要引入专门的图像库image,也就是在ETS代码开头添加下面的导包语句:

import { image } from '@kit.ImageKit';

接着先调用image.createImageSource方法,从第二步的数组缓存中获取ImageSource类型的图像来源对象。再调用ImageSource对象的createPixelMap方法,通过异步方式获得对应的PixelMap像素图数据。具体的像素图获取代码如下:

// 从字节数组中解码得到像素图对象
let imageSource = image.createImageSource(totalBuffer);
let opts: image.DecodingOptions = { editable: true };
imageSource.createPixelMap(opts).then((pixelMap) => {// 这里暂时省略对像素图pixelMap的渲染操作
}).catch((err: BusinessError) => {console.error('createPixelMap error message: ' + err.message + ', error code: ' + err.code);
});

以上获取的像素图pixelMap即可直接交给Image组件,无需转成图片文件就能在界面上显示。Image组件的渲染代码如下:

Image(this.pixelMap).width('100%').height(100).objectFit(ImageFit.Contain)

经过上述几个步骤的拼接还原过程,总算把一段一段的BASE64字符串还原为可供渲染的像素图,这样才能让图片数据以BASE64串的形式在设备间传输。

下一篇文章会介绍如何向SocketIO服务器发送图片消息。
 


http://www.mrgr.cn/news/70166.html

相关文章:

  • GIT:如何查找已删除的文件的历史记录
  • Python 获取PDF的各种页面信息(页数、页面尺寸、旋转角度、页面方向等)
  • Java面向对象编程进阶之包装类
  • D63【python 接口自动化学习】- python基础之数据库
  • JVM 中的完整 GC 流程
  • WebGIS三维地图框架--Cesium
  • kafka(启动集群,使用spring方法,自定义配置)
  • webpack 性能优化方案 - 代码分离(分包)
  • 部署Apollo 9.0-1 安装docker(阿里源安装)
  • 解读Nature:Larger and more instructable language models become less reliable
  • Android13 默认开启冻结进程
  • 电销智能机器人,怎么使用,操作复杂吗?
  • linux rocky 9.4部署和管理docker harbor私有源
  • ANDROIDWORLD: A Dynamic Benchmarking Environment for Autonomous Agents论文学习
  • Rust实战项目与未来发展——跨平台应用开发项目实践
  • 智慧机房建设整体解决方案
  • 基于h5 移动网赚项目设计与实现springboot+论文源码调试讲解
  • 【Windows】一条命令搞定文件移动与删除!`copy`、`move`、`del`详解
  • 量化研究----网格模型研究,提供源代码
  • Redis 典型应⽤-分布式锁
  • ArcGIS软件之“计算面积几何”地图制作
  • 【SSL-RL】自监督强化学习:随机潜在演员评论家 (SLAC)算法
  • Deepin 系统中安装Rider和Uno Platform
  • 《Django 5 By Example》阅读笔记:p1-p16
  • 前端-服务端渲染(SSR)和客户端渲染(CSR)的页面,在浏览器发出请求之后,分别返回的是什么
  • axios如何给某一个请求设置请求头信息