QQ登录

只需要一步,快速开始

APP扫码登录

只需要一步,快速开始

手机号码,快捷登录

手机号码,快捷登录

查看: 3627|回复: 0

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

[复制链接]

等级头衔

积分成就    金币 : 2841
   泡泡 : 1516
   精华 : 6
   在线时间 : 1294 小时
   最后登录 : 2024-11-21

丰功伟绩

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

联系方式
发表于 2021-5-31 11:44:28 | 显示全部楼层 |阅读模式
一、 概念介绍
( ^1 E; Z$ l, K: a7 V2 G0 M9 ^1. File+ G2 M+ J" U4 g6 x5 r% S/ K) E; \
(1) 通常情况下, File 对象是来自用户在一个 input 元素上选择文件后返回的 FileList 对象,也可以是来自由拖放操作生成的 DataTransfer 对象,或者来自 HTMLCanvasElement 上的 mozGetAsFile() API。
* I7 n% z! t1 Z1 N: c( B6 X! ^(2) File 对象是特殊类型的 Blob,且可以用在任意的 Blob 类型的 context 中。比如:FileReader, URL.createObjectURL(), createImageBitmap(), 及 XMLHttpRequest.send() 都能处理 Blob 和 File。0 U% T4 u% q! X/ Y) H  y
2. Blob
3 W2 ~4 t, g" Q(1) Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。
9 H5 k$ O! \- x/ y; R* b+ U(2) Blob 表示的不一定是JavaScript原生格式的数据。File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。' l8 ?& E. @3 B- n0 U
3. dataURL% T0 n. Y0 ^8 |2 ?9 h$ J/ i
(1) Data URLs,即前缀为 data: 协议的URL,其允许内容创建者向文档中嵌入小文件。0 P* A4 f( n& I* r
(2) Data URLs 由四个部分组成:前缀(data:)、指示数据类型的MIME类型、如果非文本则为可选的base64标记、数据本身:data:[][;base64],9 @' t# P! v+ l1 m4 [( }
4. canvas7 U7 E, c. A' G
(1) Canvas API 提供了一个通过JavaScript 和 HTML的 canvas 元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。, z" r! i' e  u+ ~
1.jpg
/ q: J  O( y2 T3 F' `5 g' Z" |二、相互转化" `+ a2 A& k9 M3 g6 C  k
1. File、Blob 转化成 dataURL- Q8 B9 S$ _- c3 }% {+ T
       FileReader 对象允许 Web 应用程序异步读取文件(或原始数据缓冲区)内容,使用 File 或 Blob 对象指定要读取的文件或数据。
! a' A' A7 z6 L' ]( n0 V) Q& |
  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(二进制)对象
- x0 J3 P& ]6 l4 ~2 \+ {' [2 @# G" q
  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
5 K, N4 I2 \" `* M, I9 y0 `
  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 中获取文件 dataURL
1 o! Q( P0 P2 y2 m% @; R- U; G
  1. function canvasToDataURL() {
  2.     let canvas = document.createElement('canvas')
  3.     let canvasDataURL = canvas.toDataURL('image/png', 1.0)
  4.     return canvasDataURL
  5. }
三、完整例子
1 O2 b( G( f" i6 p4 Y" ]       可以点击这里在线预览' y; f6 J* v0 @, s
2.jpg
) F4 B! c& t, b( Z: m- g( i
  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号|渝公网安备50010502503914号 )

GMT+8, 2024-11-21 19:26

Powered by paopaomj X3.5 © 2016-2025 sitemap

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