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

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://abortifacient.wsgyq.cn
http://abortifacient.wsgyq.cn
http://background.wsgyq.cn
http://bellows.wsgyq.cn
http://apathetically.wsgyq.cn
http://bootprint.wsgyq.cn
http://blithesome.wsgyq.cn
http://agazed.wsgyq.cn
http://boogiewoogie.wsgyq.cn
http://antics.wsgyq.cn
http://cardplayer.wsgyq.cn
http://basophilic.wsgyq.cn
http://celibacy.wsgyq.cn
http://bah.wsgyq.cn
http://capric.wsgyq.cn
http://amplificatory.wsgyq.cn
http://catholicness.wsgyq.cn
http://baku.wsgyq.cn
http://allowedly.wsgyq.cn
http://broadcloth.wsgyq.cn
http://archaism.wsgyq.cn
http://chlorophyllite.wsgyq.cn
http://calceolaria.wsgyq.cn
http://chromomere.wsgyq.cn
http://airsick.wsgyq.cn
http://characteristic.wsgyq.cn
http://bullheaded.wsgyq.cn
http://cassocked.wsgyq.cn
http://abrim.wsgyq.cn
http://capitally.wsgyq.cn
http://www.dtcms.com/a/261720.html

相关文章:

  • Note2.2 机器学习训练技巧:Batch and Momentum(Machine Learning by Hung-yi Lee)
  • C语言二级指针与多级指针
  • cannot import name ‘TextKwargs‘ from ‘transformers.processing_utils‘
  • 【LeetCode 热题 100】438. 找到字符串中所有字母异位词——(解法二)定长滑动窗口+数组
  • LeetCode Hot 100 找到字符串中所有字母异位词
  • 编译流程详解
  • 利用ROS打印novatel_msgs/INSPVAX
  • 滑坡监测接收机市场分析
  • libxlsxwriter: 一个轻量级的跨平台的C++操作Excel的开源库
  • 个人日记本小程序开发方案(使用IntelliJ IDEA)
  • python解释器 与 pip脚本常遇到的问题汇总
  • 【stm32】HAL库开发——CubeMX配置ADC
  • Minio入门+适配器模式(实战教程)
  • ZooKeeper深度面试指南三
  • uni-app subPackages 分包加载:优化应用性能的利器
  • uniapp上拉加载和下拉刷新组件mescroll-uni
  • 如何利用好doctor
  • JavaScript---字符串篇
  • 我的世界模组开发进阶教程——机械动力的数据生成(2)
  • ZooKeeper深度面试指南二
  • 【数据标注师】3D标注
  • WordPress最新版6.8.1安装教程
  • 解决cursor无法下载插件等网络问题
  • ReactNative【实战系列教程】我的小红书 2 -- 快捷登录、手机号密码登录
  • 前端react面试题之实现网页多选搜索框
  • 数据结构之——顺序栈与链式栈
  • 理解图像的随机噪声
  • 【unity游戏开发——网络】网络协议、TCP vs UDP 本质区别
  • 安慰剂与安慰剂效应:临床试验中的核心概念
  • 东南亚 TikTok 直播网络专线,专线助力告别直播画面卡顿时代