HarmonyOS File和base64字符串转换

1. HarmonyOS File和base64字符串转换

1.1. Base64

1.1.1. Base64认知

  Base64 是一种基于64个 ASCII 字符来表示二进制数据的表示方法,这个64个不同的字符为:
  (1)大、小写字母(A– Z、a–z)。52个
  (2)数字。(0–9)10个
  (3)两个特殊字符。(+、/)2个
在这里插入图片描述

1.1.2. Base64原理

  (1)将图片转换成二进制数据。
  (2)将8比特位为一个单元的字节数据拆分为以6个比特位为一个单元的字节数据。
  (3)将6个比特位为一个单元高位补齐00,补足8个比特。
  (4)如果剩余的字节不足6位,则先低位补00凑齐6位之后,高位再补00,补足8位。
  (5)当未编码(1中的二进制数据)输入的长度不是三的倍数时,则编码输出(3)必须添加填充,使其长度为四的倍数。填充字符为=
  (6)将补齐8个比特的二进制数据,转化为10进制数据。然后到上面的base64码表中进行查询,并生成字符。
  (7)将所有的字符进行拼接组成base64字符串。

1.1.3. 举例说明

  比如字符串:“byhk”
  (1)将其转换为二进制数据:01100010、01111001、01101000、01101011
  (2)将8比特拆为6比特:011000,100111,100101,101000,011010,11
  (3)高位补齐00,补足8个比特:0011000,0100111,00100101,00101000,00011010,00110000,
  (4)最后的11不满6位,先低位补0000变为:110000,然后高位补00,变为:00110000
  (5)步骤3,最后的数量不是4的倍数,因此需要填充两个=
  (6)因此"byhk"的base64的结果为:“Ynloaw==”
鸿蒙base64图片保存到本地沙盒

1.2. 保存base64图片到本地沙盒

  图片base64格式

data:image/png;base64,iVBORw0KGg....

1.2.1. 解析图片数据

private static dealBase64Str(base64Data: string): string {let imageData: stringif (base64Data.startsWith("data")) {const base64Split: string[] = base64Data.split(",")if (base64Split.length !== 2) {throw new Error(`Illegal base64 data`)}imageData = base64Split[1].trim()} else {imageData = base64Data}return imageData
}

1.2.2. 创建沙盒文件

private static createFile(context: Context) {let pathDir = context.filesDirlet fileName = systemDateTime.getTime(true)let filePath = `${pathDir}/${fileName}.jpg`let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)return file
}

1.2.3. 将图片数据写入

let bufferImage = buffer.from(base64Result, 'base64')
await fs.write(file.fd, bufferImage.buffer)
fs.closeSync(file.fd)

1.2.4. 完整代码

export class ImageUtils {static async saveBase64Image(base64ImageData: string, context: Context): Promise<Boolean> {try {let base64Result = ImageUtils.dealBase64Str(base64ImageData)let file = ImageUtils.createFile(context)let bufferImage = buffer.from(base64Result, 'base64')await fs.write(file.fd, bufferImage.buffer)fs.closeSync(file.fd)return Promise.resolve(true)} catch (e) {throw new Error(e)}}private static dealBase64Str(base64Data: string): string {let imageData: stringif (base64Data.startsWith("data")) {const base64Split: string[] = base64Data.split(",")if (base64Split.length !== 2) {throw new Error(`ImageUtils: Illegal base64 data`)}imageData = base64Split[1].trim()} else {imageData = base64Data}return imageData}private static createFile(context: Context) {let pathDir = context.filesDirlet fileName = systemDateTime.getTime(true)let filePath = `${pathDir}/${fileName}.jpg`let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)return file}
}

1.3. 从网页打开获取文件,并转成base64

1.3.1. 鸿蒙原生代码

import web_webview from '@ohos.web.webview';
import picker from '@ohos.file.picker';
import { BusinessError } from '@ohos.base';
import { fileIo } from '@kit.CoreFileKit';
import util from '@ohos.util';@Entry
@Component
struct UploadFile {controller:web_webview.WebviewController = new web_webview.WebviewController();@State uri: Array<string> | null = null;// // 将 ArrayBuffer 转换为 Base64 字符串// arrayBufferToBase64(buffer: ArrayBuffer): string {//   let binary = '';//   const bytes = new Uint8Array(buffer);//   for (let i = 0; i < bytes.byteLength; i++) {//     binary += String.fromCharCode(bytes[i]);//   }//   return globalThis.btoa(binary); // 使用 btoa 将二进制数据编码为 Base64// }//// btoa(binaryData: Uint8Array) {//   // 创建一个Base64Helper实例//   let base64Helper = new util.Base64Helper();//   // 使用Base64Helper将二进制数据转换为Base64编码的字符串//   return base64Helper.encodeToStringSync(new Uint8Array(binaryData));// }build() {Column(){Text('选中的图片')List(){ForEach(this.uri,(item:string)=>{ListItem(){Row(){Image(item).width('30vh').height('30vh')}}.width('30vh').height('30vh')})}.width('30vh').height('30vh')Web({src:$rawfile('setAttrAndEvent/uploadFile/index.html'),controller:this.controller}).fileAccess(false).width('100%').height('100vh').backgroundColor('grey').onShowFileSelector((event)=>{console.log('MyFileUploader onShowFileSelector invoked')let PhotoSelectOptions = new picker.PhotoSelectOptions();PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;// PhotoSelectOptions.maxSelectNumber = 5;PhotoSelectOptions.maxSelectNumber = 1;const photoPicker  = new picker.PhotoViewPicker();photoPicker .select(PhotoSelectOptions).then(async (photoSelectResult) => {this.uri = photoSelectResult.photoUris;console.info('photoPicker .select to file succeed and photoSelectResult is:' + JSON.stringify(photoSelectResult));console.info('photoPicker .select to file succeed and uri is:' + this.uri);if (this.uri.length > 0) {let oneUri = this.uri[0]// let uri: string = ''; // 这里应该是你的URIlet file = fileIo.openSync(oneUri, fileIo.OpenMode.READ_ONLY);console.info('file fd: ' + file.fd);let stat = await fileIo.stat(file.fd);// let buffer = new ArrayBuffer(4096);console.info('readSync data to file succeed and buffer size is: stat' + stat.size)let buffer = new ArrayBuffer(stat.size);let readLen = fileIo.readSync(file.fd, buffer);console.info('readSync data to file succeed and buffer size is:' + readLen);fileIo.closeSync(file);console.info('readSync data to file succeed and buffer size is: buffer 大小 ' + buffer.byteLength)// 创建一个Base64Helper实例let base64Helper = new util.Base64Helper();// 使用Base64Helper将二进制数据转换为Base64编码的字符串let base64Data = base64Helper.encodeToStringSync(new Uint8Array(buffer.slice(0, readLen)));// let base64Data = btoa(String.fromCharCode(...new Uint8Array(buffer.slice(0, readLen-1))));console.info('Base64 encoded data: ' + base64Data);}if (event) {event.result.handleFileList(this.uri);}}).catch((err: BusinessError) => {console.error(`Invoke photoPicker .select failed, code is ${err.code}, message is ${err.message}`);})return true;})}}
}

1.3.2. 关键代码

   if (this.uri.length > 0) {let oneUri = this.uri[0]// let uri: string = ''; // 这里应该是你的URIlet file = fileIo.openSync(oneUri, fileIo.OpenMode.READ_ONLY);console.info('file fd: ' + file.fd);let stat = await fileIo.stat(file.fd);// let buffer = new ArrayBuffer(4096);console.info('readSync data to file succeed and buffer size is: stat' + stat.size)let buffer = new ArrayBuffer(stat.size);let readLen = fileIo.readSync(file.fd, buffer);console.info('readSync data to file succeed and buffer size is:' + readLen);fileIo.closeSync(file);console.info('readSync data to file succeed and buffer size is: buffer 大小 ' + buffer.byteLength)// 创建一个Base64Helper实例let base64Helper = new util.Base64Helper();// 使用Base64Helper将二进制数据转换为Base64编码的字符串let base64Data = base64Helper.encodeToStringSync(new Uint8Array(buffer.slice(0, readLen)));// let base64Data = btoa(String.fromCharCode(...new Uint8Array(buffer.slice(0, readLen-1))));console.info('Base64 encoded data: ' + base64Data);}

1.3.3. html代码

<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body>
<div class="upload"><!--  点击上传按钮   --><form id="upload-form" enctype="multipart/form-data"><input type="file" id="upload" name="upload"/></form>
</div>
</body>
</html>
<style>body{width:100%;height:auto;margin:50px auto;text-align:center;background-color:#2EB3FF}
</style>

1.4. 在线图片转为base64字符串

let OutData: http.HttpResponse
http.createHttp().request("https://xxx/xxx.png",//在线图片地址
(error: BusinessError, data: http.HttpResponse) => {
if (error) {
console.error(`http reqeust failed with. Code: ${error.code}, message: ${error.message}`);
} else {
OutData = data
let code: http.ResponseCode | number = OutData.responseCode
if (ResponseCode.ResponseCode.OK === code) {
let imageData: ArrayBuffer = OutData.result as ArrayBuffer;
let base64 = new util.Base64Helper(); // 实例化Base64Helper
let data = base64.encodeSync(new Uint8Array(imageData.slice(0, imageData.byteLength))) // 转换成Uint8Array
console.info(`data长度:${data.length}`)
console.info(`data:${data}`)
let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM : true })
let retStr = textDecoder.decodeWithStream( data , {stream: false}); // 可以把Uint8Array转码成base64
}
}
}
)

1.5. 参考文档

  (1)文件下载上传:https://developer.huawei.com/consumer/cn/doc/system-Guides/network-exp-file-0000001093424975#section492510893519
  (2)载到公共目录
在沙箱目录里,在手机里看不到的。下载到公共目录可参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/request-dir-permission
  (3)预览文件
您可参考previewKit:
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/preview-introduction
  (4)Preview Kit的openPreview接口在传入文件预览信息时,当前仅支持传入文件的uri,用户文件uri介绍参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/user-file-uri-intro-V5
  (5)打开和保存PDF文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/pdf-open-docunent
  (6)@ohos.file.picker (选择器):https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-fs

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

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

相关文章

【NodeJs】【npm】npm安装electron报错

解决问题 npm安装electron报错一般来说是镜像源的问题。 electron的镜像源与一般的 vue 之类的镜像源地址不一样需要单独配置。 npm读取的全局配置一般是在 C:\Users\{用户}\.npmrc 这个配置文件中。 如果你找不到你的配置文件可以执行如下命令, # 执行后会直接用txt打开你的…

植物small RNA靶基因预测软件,psRobot

psRoto软件安装 网址 http://omicslab.genetics.ac.cn/psRobot/downloads.php下载和安装 wget http://omicslab.genetics.ac.cn/psRobot/program/WebServer/psRobot_v1.2.tar.gz # tar -zxvf psRobot_v1.2.tar.gz # cd psRobot_v1.2 ## ./configure make make installpsRot…

翻译服务器

基于UDP编程博客里的回显服务器代码,翻译服务只需要改process方法即可 所以我们可以创建一个UdpDictServer直接继承UdpEchoServer然后重写process方法 在重写的方法中完成翻译的过程 代码: package network;import java.io.IOException; import java.net.SocketException; …

初等变换 线性代数

初等变换 介绍了三种初等变换的操作。 初等矩阵 初等矩阵是干嘛的呢&#xff1f;实际上初等矩阵就是我们矩阵的初等操作&#xff0c;每一个对矩阵的初等变换操作都相当于乘上一个初等矩阵。 左乘初等矩阵就相当于对行进行初等操作&#xff0c;右乘则相当于对列进行初等操作。…

Java基础 集合框架 队列架构 双端队列 Deque

双端队列 Deque Deque 方法简介Deque 核心特点Deque实现类 ArrayDequeArrayDeque 构造方法ArrayDeque 的数据结构及实现原理ArrayDeque 方法介绍ArrayDeque 核心特性ArrayDeque 总结ArrayDeque 使用样例代码 Deque实现类 LinkedListDeque实现类 ConcurrentLinkedDeque (非阻塞线…

【Spring】——事务、整合、注解

目录 一.Spring与mybatis的整合 1.配置文件 ​编辑2. 二.事务 1.事务属性 2.传播属性 3.异常属性 4.常见配置 三.注解 1.什么是注解 2.Autowired 1.用户自定义注解 ​编辑​编辑2.JDK类型注入value 3.Bean 1.对象的创建 2.对象创建次数 3.Bean注解的注入 1.自…

Linux 离线下安装gcc、g++

描述 离线时编译Redis、nginx等编译包&#xff0c;需要gcc安装包&#xff0c;评论提醒我 上传补充 操作 1、进入gcc目录&#xff0c;并执行安装命令 rpm -ivh *.rpm --nodeps --force查看版本 gcc -v2、进入gcc-c目录&#xff0c;并执行安装 rpm -ivh *.rpm --nodeps --f…

融智学定律3:流动创造价值仅当跨域协同

关键公式意义&#xff1a; 人流方程中的 α/β 反映城市吸引力不对称性 物流优化中的 η 实现时间价值货币化 金流模型的 σ(⋅) 捕捉市场情绪突变点 信息熵的 ∥gi​−gj​∥ 度量知识势差驱动 当五流在黎曼流形上满足 ∇_μ​T^μν0&#xff08;能量动量守恒&#xff09…

趣味数据结构之——数组

你们一定都听说过它的故事…… 是的没错&#xff0c;就是一个萝卜一个坑。ಥ◡ಥ 想象一下数组就是那个坑&#xff0c;那么定义数组就是在挖坑。 元素就是萝卜。 坑就在那里(地上)&#xff0c;整整齐齐地排在那里。 于是数组最重要的一个特性就显现出来了——随机存取。还…

PR-2025《Scaled Robust Linear Embedding with Adaptive Neighbors Preserving》

核心思想分析 这篇论文的核心思想在于解决线性嵌入&#xff08;linear embedding&#xff09;与非线性流形结构之间的不匹配问题。传统方法通过保留样本点间的亲和关系来提取数据的本质结构&#xff0c;但这种方法在某些情况下无法有效捕捉到数据的全局或局部特性。此外&#…

Redis-渐进式遍历

之前使用的keys查找key,一次获取到了所有的key,当key较多时,这个操作就有可能造成Redis服务器阻塞.特别是keys *操作. 于是可以通过渐进式遍历,每次获取部分key,通过多次遍历,既查询到了所有的key,又不会卡死服务器. 渐进式遍历不是通过一个命令获取到所有元素的,而是由一组命…

ISP Pipeline(3):Lens Shading Correction 镜头阴影校正

上一篇文章讲的是&#xff1a;ISP Pipeline&#xff08;2&#xff09;&#xff1a; Black Level Compensation:ISP Pipeline&#xff08;2&#xff09;&#xff1a;Black Level Compensation 黑电平补偿-CSDN博客 视频&#xff1a;(4) Lens Shading Correction | Image Signal…

什么是WebAssembly(WASM)

WebAssembly&#xff08;WASM&#xff09; 是一种高性能的低级编程语言字节码格式&#xff0c;可在网页和非网页环境中运行&#xff0c;支持多语言编译&#xff0c;运行速度接近原生代码。它在区块链中的作用是&#xff1a;作为智能合约的执行引擎&#xff0c;被多条非以太坊链…

【C++】inline的作用

一、inline的作用 1.1函数内联 作用​&#xff1a;建议编译器将函数调用替换为函数体代码&#xff0c;减少函数调用的开销&#xff08;压栈/跳转&#xff09;。​注意​&#xff1a;这只是对编译器的建议&#xff0c;编译器可能忽略&#xff08;如函数体过大或递归&#xff0…

代码随想录|图论|04广度优先搜索理论基础

广搜的使用场景 广搜的搜索方式就适合于解决两个点之间的最短路径问题。 因为广搜是从起点出发&#xff0c;以起始点为中心一圈一圈进行搜索&#xff0c;一旦遇到终点&#xff0c;记录之前走过的节点就是一条最短路。 当然&#xff0c;也有一些问题是广搜 和 深搜都可以解决…

Xposed框架深度解析:Android系统级Hook实战指南

引言:Android系统定制化的革命性突破 在移动安全研究和系统优化领域,传统的APP修改方案面临​​三重技术瓶颈​​: ​​逆向工程壁垒​​:APK重打包方案需处理签名校验、代码混淆等防护,平均耗时增加200%​​兼容性挑战​​:Android碎片化导致设备适配率不足65%​​功能…

大模型在通讯网络中的系统性应用架构

一、网络架构智能化重构​​ ​​1.1 空天地一体化组网优化​​ 智能拓扑动态调整​​&#xff1a;大模型通过分析卫星轨道数据、地面基站负载及用户分布&#xff0c;实时优化天地一体化网络拓扑。例如&#xff0c;在用户密集区域&#xff08;如城市中心&#xff09;自动增强低…

软件测试进阶:Python 高级特性与数据库优化(第二阶段 Day6)

在掌握 SQL 复杂查询和 Python 数据库基础操作后&#xff0c;第六天将深入探索Python 高级编程特性与数据库性能优化。通过掌握 Python 的模块与包管理、装饰器等高级语法&#xff0c;结合数据库索引优化、慢查询分析等技术&#xff0c;提升测试工具开发与数据处理效率。 一、…

【NLP】自然语言项目设计04

目录 04模型验证 代码架构核心设计说明 05运行推理 代码架构核心设计说明 项目展望 项目简介 训练一个模型&#xff0c;实现歌词仿写生成 任务类型&#xff1a;文本生成&#xff1b; 数据集是一份歌词语料&#xff0c;训练一个模型仿写歌词。 要求 1.清洗数据。歌词语料…

数据结构1 ——数据结构的基本概念+一点点算法

数据结构算法程序设计 什么是数据结构 数据&#xff08;data&#xff09;&#xff1a;符号集合&#xff0c;处理对象。 数据元素&#xff08;data element&#xff09;&#xff0c;由数据项&#xff08;data item&#xff09; 组成。 关键字&#xff08;key&#xff09;识别…