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

news2024/11/24 11:50:56

文章目录

    • 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);
        // 先转为base64
        let 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数据转换为Blob
          var 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类型 涉及到异步 所以要用 promise
        let 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类型 涉及到异步 所以要用 promise
        let blob = await fileToBlob(file);
        console.log("blob:", blob);
      };

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

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

  /**
   * 获取文件(图片视频等)的本地内存地址 可以直接访问
   * @param file  该文件的文件流
   */
  export function createObjectURLFun(file) {
    let url = '';
    if (window.createObjectURL != undefined) {
      // basic
      url = window.createObjectURL(file);
    } else if (window.URL != undefined) {
      // mozilla(firefox)
      url = window.URL.createObjectURL(file);
    } else if (window.webkitURL != undefined) {
      // webkit or chrome
      url = 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';
      }
      // 第二版 dataLoad
      video.addEventListener(listen, () => {
        console.log("我走了");
        canvas.width = width;
        canvas.height = height;
        canvas.getContext('2d').drawImage(video, 0, 0, width, height); //绘制canvas
        dataURL = canvas.toDataURL('image/jpeg'); //转换为base64
        resolve(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.coloradmin.cn/o/893505.html

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

相关文章

postmarketOS

主步骤 #以下全程插入usb线 fastboot devices fastboot getvar all fastboot erase userdata fastboot erase system fastboot erase cachepmbootstrap init pmbootstrap installpmbootstrap flasher flash_rootfs --partition userdata pmbootstrap flasher flash_kernel…

盘点哪些好用的开放式耳机有哪些?开放式蓝牙耳机排行榜推荐

​你是否厌倦了传统耳机的束缚&#xff1f;是否渴望一种更为自由的听音体验&#xff1f;开放式耳机&#xff0c;将为你打开一扇全新的听觉大门。开放式耳机采用不入耳设计&#xff0c;让你在享受音乐的同时&#xff0c;保持对外界的感知&#xff0c;随时随地&#xff0c;尽享自…

图片展示 JAVA

利用Java中提供的 ImageIcon类和JLabel类加载与显示电脑路径中的图片&#xff0c;并最终展示在JFrame类窗口中。 代码&#xff1a; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel;public class Main extends JFrame {//继承父类Jframe…

智能画笔:如何利用AI绘画API打造独特的创作风格

在当今数字化时代&#xff0c;人工智能的迅猛发展正深刻地影响着各个领域&#xff0c;艺术创作也不例外。AI绘画 API 作为一种创新的工具&#xff0c;为艺术家提供了独特的机会&#xff0c;使他们能够在创作过程中借助人工智能技术&#xff0c;打造出独具个性的创作风格。本文将…

Linux系统中lib64文件夹下包含:动态链接库,静态链接库,内核模块等

lib64 目录对系统稳定运行有重要作用。 目录 lib64文件动态链接库静态链接库内核模块 lib64文件 lib64 文件夹存放主要是可被程序直接加载并使用的 64 位代码模块,包括动态库、静态库、内核模块等,这些文件对程序运行都至关重要。 在 Linux 系统中,lib64 文件夹通常用于存放…

阿里巴巴面试高频题:JVM内存模型通俗解释!

大家好&#xff0c;我是你们的小米&#xff0c;今天我要和大家一起来探讨一个热门话题——JVM内存模型&#xff01;作为计算机科班出身的小米&#xff0c;一直对技术充满热情&#xff0c;喜欢和大家分享各种有趣的知识。最近在准备阿里巴巴的面试时&#xff0c;遇到了一个非常有…

电力系统基础知识(一)—电力系统概述

1、电压 也称作电势差或电位差&#xff0c;是衡量单位电荷在静电场中由于电势不同所产生的能量差的物理量。其大小等于单位正电荷因受电场力作用从A点移动到B点所做的功,电压的方向规定为从高电位指向低电位。其单位为伏特(V,简称伏),常用单位还有千伏(kV)、毫伏(mV)、微伏(uV…

如何选择适合企业的会计软件:关键因素解析

会计软件的出现&#xff0c;帮助企业解决了一些繁杂琐碎的财务工&#xff0c;提高企业财务管理效率。因此会计软件受到了越来越多的企业的青睐。会计软件市场也越来越壮大&#xff0c;那么企业该如何挑选到适合自己的会计软件呢&#xff1f; 会计软件挑选关键因素 1. 业务需求…

比较海思麒麟810与高通骁龙855的优劣

海思麒麟810与高通骁龙855可以从以下几方面进行比较: 一、CPU比较 海思麒麟810还是高通骁龙855——哪个处理器更快?在这个比较中,我们观察了差异,并分析了这两个CPU中哪一个更好。我们比较了技术数据和基准测试结果。 海思麒麟810有8个内核和8个线程,时钟最高频率为2.2…

【数据结构与算法】队列

文章目录 一&#xff1a;队列1.1 队列的概念1.2 队列的介绍1.3 队列示意图 二&#xff1a;数组模拟队列2.1 介绍2.2 思路2.3 代码实现2.3.1 定义队列基本信息2.3.2 初始化队列2.3.3 判断队列是否满&#xff0c;是否为空2.3.4 添加数据到队列2.3.5 获取队列数据&#xff0c;出队…

springcloud3 hystrix实现服务熔断的案例配置3

一 hystrix的熔断原理 1.1 hystrix的熔断原理 在springcloud的框架里&#xff0c;熔断机制是通过hystrix实现&#xff0c;hystrix会监控服务之间的调用。当失败调用达到一定的阈值&#xff0c;默认是5s内失败20次&#xff0c;就会启用hystrix的熔断机制&#xff0c;使用命Hy…

Codeforces Round 893 (Div. 2) A ~ C

比赛链接 A. Buttons 博弈、最优策略一定是先去按都能按的按钮&#xff0c;按完之后再按自己的。 #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl \nusing namespace std;typedef pair<int, int> PII; typede…

国产CS5523规格书|MIPI转EDP方案设计|替代LT8911芯片电路原理|ASL集睿致远CS替代龙讯

ASL芯片&#xff08;集睿致远&#xff09; CS5523是一款MIPI DSI输入&#xff0c;DP/e DP输出转换芯片&#xff0c;可pin to pin替代LT8911龙讯芯片。 MIPI DSI 最多支持 4 个通道&#xff0c;每个通道的最大运行速度为 1.5Gps。对于DP 1.2输出&#xff0c;它支持1.62Gbps和2.…

Redis 数据库 NoSQL

目录 一、NoSQL 二、为什么会出现NoSQL技术 三、NoSQL的类别 键值&#xff08;Key-Value&#xff09;存储数据库 列存储数据库 文档型数据库 图形&#xff08;Graph&#xff09;数据库 四、NoSQL适应场景 五、在分布式数据库中CAP原理 1、CAP 2、BASE 一、NoSQL NoS…

Cat(5):API介绍—Event

Event 用来记录一件事发生的次数&#xff0c;比如记录系统异常&#xff0c;它和transaction相比缺少了时间的统计&#xff0c;开销比transaction要小。 Cat.logEvent 记录一个事件。 Cat.logEvent("URL.Server", "serverIp", Event.SUCCESS, "ip${…

萤石网络2023上半年报:利润同比增长70%,技术、市场多核驱动

近年来&#xff0c;随着人工智能技术快速发展&#xff0c;智能家居热度在持续升温&#xff0c;市场规模在不断扩大。Omida最新报告显示&#xff0c;到2026年&#xff0c;全球智能家居设备市场规模将超2790亿美元&#xff0c;逾3亿家庭将共同创造智能家居服务收入。中国作为全球…

APP外包开发原生和H5的区别

原生开发和H5开发是两种不同的方法&#xff0c;用于创建移动应用程序。它们具有各自的特点、优势和劣势&#xff0c;适用于不同的应用场景。以下是原生开发和H5开发之间的一些主要区别&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发…

如何在微信内置浏览器中开启开发者模式(f12)

本文转载于&#xff1a;https://blog.csdn.net/qq_45863248/article/details/127688137 重要的事情放开头&#xff1a;此方法适用于3.2.1版本微信&#xff0c;如不想回退版本&#xff0c;就不用往下看了 相信大家都使用过浏览器的f12&#xff0c;可以看到浏览器所有的通讯数据…

3.若依前后端分离版开发用户自定义配置表格功能

一、背景 在项目上线测试的时候,关于同一个界面的表格,不同的用户会出现不同的字段排列需求,有些用户希望把A字段排在最前面,有些用户则希望A字段不显示。针对这种情况,开发一个表格自定义配置的功能,每个用户根据自己的需求自己去设定表单字段的显示、隐藏、字段的宽度…

水浒传思维导图怎么绘制?试试这样绘制

水浒传思维导图怎么绘制&#xff1f;绘制水浒传思维导图可以帮助我们更好地理解和记忆水浒传的故事情节和人物关系。通过将大量信息组织成一个视觉图&#xff0c;我们可以更清晰地看到每个人物的特点和角色关系&#xff0c;更好地理解整个故事的发展和结构。此外&#xff0c;绘…