QQ登录

只需要一步,快速开始

APP扫码登录

只需要一步,快速开始

手机号码,快捷登录

查看: 3422|回复: 0

[HTML/CSS/JS] File、Blob、dataURL 和 canvas 的应用与转换

[复制链接]

等级头衔

积分成就    金币 : 2810
   泡泡 : 1516
   精华 : 6
   在线时间 : 1245 小时
   最后登录 : 2024-5-18

丰功伟绩

优秀达人突出贡献荣誉管理论坛元老

联系方式
发表于 2021-5-31 11:44:28 | 显示全部楼层 |阅读模式
一、 概念介绍
; I6 o6 A: z6 d4 T1. File/ D4 x  Y* i0 {& g$ d& h- a+ w
(1) 通常情况下, File 对象是来自用户在一个 input 元素上选择文件后返回的 FileList 对象,也可以是来自由拖放操作生成的 DataTransfer 对象,或者来自 HTMLCanvasElement 上的 mozGetAsFile() API。  R2 N- Z  G1 c. Y# W# |6 q% f
(2) File 对象是特殊类型的 Blob,且可以用在任意的 Blob 类型的 context 中。比如:FileReader, URL.createObjectURL(), createImageBitmap(), 及 XMLHttpRequest.send() 都能处理 Blob 和 File。
' L. a/ [. W! x* X2. Blob2 {2 J+ y( k0 ~' Q  A6 ]0 E
(1) Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。
+ s4 {  n' g) h! D+ B$ p(2) Blob 表示的不一定是JavaScript原生格式的数据。File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。
; i6 q; v' }. L: M: k) t1 G& |3. dataURL. [" c/ l, r& C( L, {
(1) Data URLs,即前缀为 data: 协议的URL,其允许内容创建者向文档中嵌入小文件。
, }7 f  A. L8 T(2) Data URLs 由四个部分组成:前缀(data:)、指示数据类型的MIME类型、如果非文本则为可选的base64标记、数据本身:data:[][;base64],) y0 e! _; I4 Q/ O6 s4 i
4. canvas) t% T5 w0 J: v# z7 D0 O
(1) Canvas API 提供了一个通过JavaScript 和 HTML的 canvas 元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。
" K) V0 `; o; I5 g 1.jpg 1 J; V! J, v7 r  b% H
二、相互转化
; Q0 c; G0 y/ P4 Y. j1. File、Blob 转化成 dataURL
# d: X5 A9 j* u: j" g       FileReader 对象允许 Web 应用程序异步读取文件(或原始数据缓冲区)内容,使用 File 或 Blob 对象指定要读取的文件或数据。
$ |$ w% @$ E3 }
  1. function fileToDataURL(file) {
  2.     let reader = new FileReader()
  3.     reader.readAsDataURL(file)
  4.     // reader 读取文件成功的回调
  5.     reader.onload = function(e) {
  6.       return reader.result
  7.     }
  8. }
2. dataURL(base64) 转化成 Blob(二进制)对象/ U1 V8 q& P' ]  ~! J. |& c
  1. function dataURLToBlob(fileDataURL) {
  2.     let arr = fileDataURL.split(','),
  3.         mime = arr[0].match(/:(.*?);/)[1],
  4.         bstr = atob(arr[1]),
  5.         n = bstr.length,
  6.         u8arr = new Uint8Array(n);
  7.     while(n --) {
  8.       u8arr[n] = bstr.charCodeAt(n)
  9.     }
  10.     return new Blob([u8arr], {type: mime})
  11. }
3. File, Blob 文件数据绘制到 canvas
/ J& n' h$ a/ G* }: S. y
  1. // 思路:File, Blob ——> dataURL ——> canvas
  2. function fileAndBlobToCanvas(fileDataURL) {
  3.     let img = new Image()
  4.     img.src = fileDataURL
  5.     let canvas = document.createElement('canvas')
  6.     if(!canvas.getContext) {
  7.       alert('浏览器不支持canvas')
  8.       return;
  9.     }
  10.     let ctx = canvas.getContext('2d')
  11.     document.getElementById('container').appendChild(canvas)
  12.     img.onload = function() {
  13.       ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
  14.     }
  15. }
4. 从 canvas 中获取文件 dataURL6 j; y& B5 k* N5 L
  1. function canvasToDataURL() {
  2.     let canvas = document.createElement('canvas')
  3.     let canvasDataURL = canvas.toDataURL('image/png', 1.0)
  4.     return canvasDataURL
  5. }
三、完整例子
- ?( [4 h" z+ l* n4 @% V& B: n7 U       可以点击这里在线预览$ j2 R, m5 b  N% \+ _, |- U
2.jpg

+ |  {( K: v/ z) }9 w7 _
  1. <!--
  2. * @information: datadURL File Blob canvas 的互相转化
  3. *
  4. * File.prototype instanceof Blob === true
  5. * Blob.prototype instanceof Object === true
  6. -->
  7. <!DOCTYPE html>
  8. <html>
  9. <head>
  10.   <meta charset="UTF-8">
  11.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  12.   <title>datadURL File Blob canvas</title>
  13.   <style>
  14.     .body {
  15.       text-align: center;
  16.     }
  17.     .img-box {
  18.       margin: 20px 0;
  19.     }
  20.     #img {
  21.       width: 60%;
  22.     }
  23.   </style>
  24. </head>
  25. <body>
  26.   
  27.   <div class="body">
  28.     <div class="input-box">
  29.       <input id="input" type="file" accept="image/png, image/jpeg" onchange="onChangeInput()">
  30.     </div>
  31.    
  32.     <div class="img-box">
  33.       img:
  34.       <img src="" alt="img" id="img">
  35.     </div>
  36.     <div class="canvas-box" id="canvas-box">
  37.       canvas:
  38.     </div>
  39.   </div>
  40. <script>
  41.   // 文件对象
  42.   let file;
  43.   // 文件 base64 码
  44.   let fileDataURL;
  45.   /**
  46.    * @information: 获取文件
  47.    */
  48.   function onChangeInput() {
  49.     file = document.getElementById('input').files[0]
  50.     console.log('file->', file)
  51.     if(!FileReader) {
  52.       alert('浏览器版本过低,请升级版本')
  53.       return;
  54.     }
  55.     fileToDataURL()
  56.   }
  57.   
  58.   /**
  59.    * @information: 使用 FileReader 读取文件内容, File(二进制) ——> dataURL(base64)   Blob ——> dataURL 同理
  60.    */
  61.   function fileToDataURL() {
  62.     let reader = new FileReader()
  63.     reader.readAsDataURL(file)
  64.     reader.onload = function(e) {
  65.       console.log('dataURL->', reader.result)
  66.       fileDataURL = reader.result
  67.       showImg()
  68.       dataURLToBlob()
  69.     }
  70.   }
  71.   /**
  72.    * @information: 图片回显
  73.    */
  74.   function showImg() {
  75.     let img = document.getElementById('img')
  76.     img.src = fileDataURL
  77.   }
  78.   /**
  79.    * @information: dataURL(base64) ——> Blob(二进制)对象
  80.    */
  81.   function dataURLToBlob() {
  82.     let arr = fileDataURL.split(','),
  83.         mime = arr[0].match(/:(.*?);/)[1],
  84.         bstr = atob(arr[1]),
  85.         n = bstr.length,
  86.         u8arr = new Uint8Array(n);
  87.     while(n --) {
  88.       u8arr[n] = bstr.charCodeAt(n)
  89.     }
  90.     console.log('blob->', new Blob([u8arr], {type: mime}))
  91.     fileAndBlobToCanvas()
  92.     return new Blob([u8arr], {type: mime})
  93.   }
  94.   /**
  95.    * @information: File, Blob 文件数据绘制到 canvas
  96.    * 思路:File, Blob ——> dataURL ——> canvas
  97.    */
  98.   function fileAndBlobToCanvas() {
  99.     let img = new Image()
  100.     img.src = fileDataURL
  101.     let canvas = document.createElement('canvas')
  102.     if(!canvas.getContext) {
  103.       alert('浏览器不支持canvas')
  104.       return;
  105.     }
  106.     let ctx = canvas.getContext('2d')
  107.     document.getElementById('canvas-box').appendChild(canvas)
  108.     img.onload = function() {
  109.       ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
  110.       canvasToDataURL()
  111.     }
  112.   }
  113.   /**
  114.    * @information: 从 canvas 中获取文件 dataURL
  115.    */
  116.   function canvasToDataURL() {
  117.     let canvas = document.createElement('canvas')
  118.     let canvasDataURL = canvas.toDataURL('image/png', 1.0)
  119.     console.log('从 canvas 中获取文件 dataURL :', canvasDataURL)
  120.   }
  121. </script>
  122. </body>
  123. </html>
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|paopaomj.COM ( 渝ICP备18007172号 )

GMT+8, 2024-5-20 01:35

Powered by paopaomj X3.4 © 2016-2024 sitemap

快速回复 返回顶部 返回列表