前端对文件转换处理的一些常用方法

news/2024/11/17 21:39:02/

文章目录

    • 0,前言
    • 1,将图片的url网络链接(http://) 转为base64格式
    • 2,将base64的图片数据转换为file文件
    • 3,将以base64的图片数据转换为Blob
    • 4,将file文件转化为base64
    • 5,将file文件转换为Blob
    • 6,获取文件(图片视频等)的本地内存地址 可以直接访问
    • 7,视频截帧(截取视频的第一帧)
    • 8,总结

本篇文章侧重点是对图片文件的处理,比如url转file、转base64;file转blob类型等。

注意:不要把视频文件转成base64,因为base64格式本质是一串很长的字符串,如果在手机端上传大一点的视频文件并有转bsee64的操作,那么就会导致页面自动刷新、程序崩溃、甚至浏览器直接被系统杀掉,因为视频的base64字符串太大会撑报内存的。

如果上传视频文件后,想要对视频的回显可以使用createObjectUrl()方法来生成临时的内存地址来访问。


0,前言

JavaScript 提供了一些 API 来处理文件或原始文件数据,例如:File、Blob、FileReader、ArrayBuffer、base64 等; 了解它们会对下面的一些方法更容易理解;

推荐阅读以下博客

(知乎):1,https://zhuanlan.zhihu.com/p/568915443
(csdn):2,https://blog.csdn.net/mrlaochen/article/details/120209650

在这里插入图片描述



1,将图片的url网络链接(http://) 转为base64格式

/*** 将图片的url网络链接(http://) 转为base64格式* @param {string}*/export function imgUrlToBase64(imgUrl) {return new Promise((resolve) => {var img = new Image();img.src = imgUrl;// 设置图片跨域属性img.setAttribute("crossOrigin", "anonymous");// 注意 onload是异步的行为img.onload = () => {var canvas = document.createElement("canvas");canvas.width = img.width;canvas.height = img.height;var ctx = canvas.getContext("2d");ctx.drawImage(img, 0, 0);var dataURL = canvas.toDataURL("image/png");resolve(dataURL);};});
}

使用如下:

      // 网络图片链接let finalImg = "https://img0.baidu.com/it/u=3021883569,1259262591&fm=253&fmt=auto&app=120&f=JPEG?w=1140&h=641";// 开始使用imgUrlToBase64(finalImg).then((res) => {console.log("res:", res);});

2,将base64的图片数据转换为file文件

/*** 将以base64的图片数据转换为File文件* @param {string}*/
export function base64ToFile(dataUrl, fileName = "myFile") {let arr = dataUrl.split(",");let mime = arr[0].match(/:(.*?);/)[1];let suffix = mime.split("/")[1];let bstr = atob(arr[1]);let n = bstr.length;let u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}return new File([u8arr], `${fileName}.${suffix}`, {type: mime});
}

使用案例

      <input type="file" />// 原生添加点击事件document.getElementsByTagName("input")[0].onchange = async function (e) {// 拿到的文件类型let file = e.target.files[0];console.log("file:",file);// 先转为base64let base64 = await fileTransferBase64(file);// 将以base64的图片url数据转换为File文件let file2 = base64ToFile(base64)  ================注意看这行===================console.log("file2:", file2);};

3,将以base64的图片数据转换为Blob

/*** 将以base64的图片数据转换为Blob * @param urlData 用url方式表示的base64图片数据*/function base64UrlToBlob(urlData, filename) {try {if (urlData == "" || !urlData) {return console.warn("urlData不存在");}if (!filename) {filename = "myfile";}// 以base64的图片url数据转换为Blobvar arr = urlData.split(","),mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]),n = bstr.length,u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}let bold = new Blob([u8arr], { type: mime });return { bold, filename };} catch (error) {console.warn("base64转换为Blob出问题了:", error);}}

使用案例

 	  <input type="file" />// 原生添加点击事件document.getElementsByTagName("input")[0].onchange = async function (e) {// 拿到的文件类型let file = e.target.files[0];console.log("file:", file);let base64 = await fileTransferBase64(file);// 将以base64的图片url数据转换为File文件let blob = base64UrlToBlob(base64);  =======注意这行=========console.log("blob:", blob);};

4,将file文件转化为base64

  /*** 将file文件转化为base64 使用promise* @param file 该文件的file类型*/export function fileTransferBase64(file) {try {return new Promise((resolve, reject) => {const reader = new FileReader(); //异步读取reader.readAsDataURL(file);// 成功和失败返回对应的信息,reader.result一个base64,可以直接使用reader.onload = (e) => {resolve(e.target.result);};// 失败返回失败的信息reader.onerror = (error) => {console.warn('file文件转化为base64s失败:', error);reject(error);};});} catch (error) {console.warn('捕获fileTransferBase64方法的错误:', error);}}

使用案例

转file类型 涉及到异步 所以要用 promise 来封装一下;

      <input type="file" />// 原生添加点击事件document.getElementsByTagName("input")[0].onchange = async function (e) {// 拿到的文件类型let file = e.target.files[0];// 转file类型 涉及到异步 所以要用 promiselet base64 = await fileTransferBase64(file)console.log("base64:",base64);};

5,将file文件转换为Blob

  /*** 直接将file数据转换为Blob * @param file格式*/export function fileToBlob(file) {return new Promise((resolve, reject) => {// FileReader  异步读取文件const reader = new FileReader();// readAsDataURL: dataurl它的本质就是图片的二进制数据, 进行base64加密后形成的一个字符串,reader.readAsDataURL(file);// 成功和失败返回对应的信息,reader.result一个base64,可以直接使用reader.onload = (e) => {let arr = e.target.result.split(',');let mime = arr[0].match(/:(.*?);/)[1];console.log(mime);const blob = new Blob([e.target.result], { type: mime });resolve(blob);};// 失败返回失败的信息reader.onerror = (error) => {console.warn('file数据转换为Blob失败:', error);reject(error);};});}

使用案例

转blob类型也涉及到异步 所以要用 promise 来封装一下;

      <input type="file" />// 原生添加点击事件document.getElementsByTagName("input")[0].onchange = async function (e) {// 拿到的文件类型let file = e.target.files[0];// 转file类型 涉及到异步 所以要用 promiselet blob = await fileToBlob(file);console.log("blob:", blob);};

6,获取文件(图片视频等)的本地内存地址 可以直接访问

此方法可以用来上传文件之后的回显。

  /*** 获取文件(图片视频等)的本地内存地址 可以直接访问* @param file  该文件的文件流*/export function createObjectURLFun(file) {let url = '';if (window.createObjectURL != undefined) {// basicurl = window.createObjectURL(file);} else if (window.URL != undefined) {// mozilla(firefox)url = window.URL.createObjectURL(file);} else if (window.webkitURL != undefined) {// webkit or chromeurl = window.webkitURL.createObjectURL(file);}return url;}

使用案例

      // 原生添加点击事件document.getElementsByTagName("input")[0].onchange = async function (e) {// 拿到的文件类型let file = e.target.files[0];let objectURL = createObjectURLFun(file)console.log("objectURL:", objectURL); //打印结果:  objectURL: blob:null/31fff142-4b83-4749-b71d-a9a4f6c16a43};

7,视频截帧(截取视频的第一帧)

常用上传视频文件后截取视频文件的第一帧当做封面使用;

第一种:

/*** 获取视频的第一帧 来当做封面  * @param url 视频的url 可以是一个由window.URL.createObjectURL返回的视频内存临时地址(推荐使用)*/
export function getFirstImg(url) {return new Promise(function (resolve, reject) {try {let dataURL = '';let width = '90'; // 单位是px 可以随意更改let height = '90';let listen = 'canplay';//需要监听的事件let video = document.createElement('video');let canvas = document.createElement('canvas');//使用严格模式('use strict');video.setAttribute('crossOrigin', 'anonymous'); //处理跨域video.setAttribute('src', url);video.setAttribute('width', width);video.setAttribute('height', height);video.currentTime = 1; // 第一帧video.preload = 'auto'; //metadata:抓取原数据//判断IOS 监听 durationchange或progress  但是在ios会出现黑屏if (/iPad|iPhone|iPod/.test(navigator.userAgent)) {video.load();video.autoplay = true;video.muted = true; //静音listen = 'loadeddata';}// 第二版 dataLoadvideo.addEventListener(listen, () => {console.log("我走了");canvas.width = width;canvas.height = height;canvas.getContext('2d').drawImage(video, 0, 0, width, height); //绘制canvasdataURL = canvas.toDataURL('image/jpeg'); //转换为base64resolve(dataURL);});} catch (error) {console.log('视频截帧的失败报错:', error);}});
}

第二种:

export function getFirstImg2(url) {const video = document.createElement("video");video.crossOrigin = "anonymous"; // 允许url跨域video.autoplay = true; // 自动播放video.muted = true; // 静音video.src = url;return new Promise((resolve, reject) => {try {video.addEventListener("loadedmetadata",() => {console.log("loadedmetadata");video.currentTime = 2;const canvas = document.createElement("canvas");video.addEventListener("canplaythrough", () => {console.log("canplaythrough");canvas.width = video.videoWidth;canvas.height = video.videoHeight;canvas.getContext("2d").drawImage(video, 0, 0, canvas.width, canvas.height);const firstFrame = canvas.toDataURL();// console.log(firstFrame); // 输出第一帧画面的Base64编码字符串resolve(firstFrame);});},{ once: true });} catch (err) {console.error(err);reject("");}});
}

8,总结

以上的几个方法如果使用了new Promise 说明里面存在异步操作,那么在调用的时候要使用 .then来获取转换后的文件。或直接使用 async await 语法进行接收resolve ()方法返回的文件;

保证代码能够同步运行,避免预料之外的问题;


http://www.ppmy.cn/news/1043651.html

相关文章

在海外如何进行应用商店的关键词优化

分析市场&#xff0c;了解我们的应用类别&#xff0c;将我们的应用与竞争对手的优点和缺点进行比较&#xff0c;找到市场上的空白或所谓未满足的需求&#xff0c;并思考如何填补。 1、应用商店关键词优化。 关键词优化的目的是找到最相关的关键词 &#xff0c;并测试应用元数据…

Focus-DETR利用双重注意力机制重建编码器,打造最强目标检测模型

前期的文章我们介绍了DETR模型,我们知道DETR模型首先使用CNN卷积神经网络搜集图片的核心特征点,然后把这些特征点整合起来,通过embedding方法,把特征图片转换到特征向量空间。然后根据标准Transformer模型的编码器与解码器进行注意力机制的计算,最后把计算后的数据进行图片…

稚晖君人形机器人问世:大模型加持,会自己换胳膊,要上生产线造车

从零开始,不到半年就造出人形机器人,还自带软硬件体系。 大模型技术的新一波浪潮:具身智能,已经有了重要进展。 刚刚,稚晖君的创业公司「智元机器人」开了自己的第一场发布会。 以「天才少年」身份加入华为的稚晖君(彭志辉)于去年底宣布离职创业,人们都在关注他在机器…

寻路算法(Java 实例代码源码包下载)

目录 寻路算法 Java 实例代码 src/runoob/graph/Path.java 文件代码&#xff1a; 寻路算法 图的寻路算法也可以通过深度优先遍历 dfs 实现&#xff0c;寻找图 graph 从起始 s 点到其他点的路径&#xff0c;在上一小节的实现类中添加全局变量 from数组记录路径&#xff0c;fr…

SpringBoot + Vue 微人事(十)

职位管理前后端接口对接 先把table中的数据展示出来&#xff0c;table里面的数据实际上是positions里面的数据&#xff0c;就是要给positions:[] 赋上值 可以在methods中定义一个initPosition方法 methods:{//定义一个初始化positions的方法initPositions(){//发送一个get请求…

shell脚本文本三剑客sed

shell脚本文本三剑客sed 一.Sed编辑器1.1sed概述1.2sed工作流程1.3sed基本法1.4sed常用选项1.5sed命令的常用操作 二.sed命令使用2.1打印内容2.2删除内容示例5&#xff1a;先备份内容在删除2.3插入内容2.4取反2.5搜索替代2.6分组调用 一.Sed编辑器 1.1sed概述 sed编辑器是一种…

Harmony OS教程学习笔记

基础知识 1.如何修改程序启动的第一个页面&#xff1f; 不想使用创建的默认的页面&#xff0c;这时需要修改启动页面&#xff0c;修改的地方在EntryAbility文件中的onWindowStageCreate方法中。 onWindowStageCreate(windowStage: window.WindowStage) {// Main window is cr…

九耶丨阁瑞钛伦特-在项目中找到的经典BUG是什么?

在项目中找到的经典BUG有很多种&#xff0c;以下是其中一些常见的例子&#xff1a; 空指针异常&#xff08;NullPointerException&#xff09;&#xff1a;当程序试图访问一个空对象或未初始化的变量时&#xff0c;会抛出空指针异常。这通常是由于缺少对变量的正确初始化或检查…