zoukankan      html  css  js  c++  java
  • File、Blob、dataURL 和 canvas 的应用与转换

    File、Blob、dataURL 和 canvas 的应用与转换

    一、 概念介绍

    1. File

    (1) 通常情况下, File 对象是来自用户在一个 <input> 元素上选择文件后返回的 FileList 对象,也可以是来自由拖放操作生成的 DataTransfer 对象,或者来自 HTMLCanvasElement 上的 mozGetAsFile() API。

    (2) File 对象基于 Blob,是特殊类型的 Blob,且可以用在任意的 Blob 类型的 context 中。比如:FileReader, URL.createObjectURL(), createImageBitmap(), 及 XMLHttpRequest.send() 都能处理 Blob 和 File。


    2. Blob

    (1) Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。

    (2) Blob 表示的不一定是 JavaScript 原生格式的数据。File 接口基于 Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。


    3. dataURL

    (1) Data URLs,即前缀为 data: 协议的 URL,其允许内容创建者向文档中嵌入小文件。

    (2) Data URLs 由四个部分组成:前缀(data:)、指示数据类型的 MIME 类型、如果非文本则为可选的 base64 标记、数据本身:data:[][;base64],


    4. canvas

    (1) Canvas API 提供了一个通过 JavaScript 和 HTML 的 <canvas> 元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。


    关系图

    二、相互转化

    1. File、Blob 转化成 dataURL

    FileReader 对象允许 Web 应用程序异步读取文件(或原始数据缓冲区)内容,使用 File 或 Blob 对象指定要读取的文件或数据。

    function fileToDataURL(file) {
      let reader = new FileReader()
      reader.readAsDataURL(file)
      // reader 读取文件成功的回调
      reader.onload = function (e) {
        return reader.result
      }
    }
    

    2. dataURL(base64) 转化成 Blob(二进制)、File 对象

    // dataURL 转为 Blob
    function dataURLToBlob(fileDataURL) {
      let arr = fileDataURL.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new Blob([u8arr], { type: mime })
    }
    
    // dataURL 转为 File
    function dataURLToBlob(fileDataURL, filename) {
      let arr = fileDataURL.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], filename, { type: mime })
    }
    

    3. File, Blob 文件数据绘制到 canvas

    // 思路:File, Blob ——> dataURL ——> canvas
    
    function fileAndBlobToCanvas(fileDataURL) {
      let img = new Image()
      img.src = fileDataURL
      let canvas = document.createElement('canvas')
      if (!canvas.getContext) {
        alert('浏览器不支持canvas')
        return
      }
      let ctx = canvas.getContext('2d')
      document.getElementById('container').appendChild(canvas)
      img.onload = function () {
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
      }
    }
    

    4. 从 canvas 中获取文件 dataURL

    function canvasToDataURL() {
      let canvas = document.createElement('canvas')
      let canvasDataURL = canvas.toDataURL('image/png', 1.0)
      return canvasDataURL
    }
    

    三、完整栗子

    可以点击 这里 在线预览

    预览图

    <!--
     * @Date: 2020-11-22 14:33:55
     * @information: datadURL File Blob canvas 的互相转化
     *
     * File.prototype instanceof Blob === true
     * Blob.prototype instanceof Object === true
    -->
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>datadURL File Blob canvas</title>
      <style>
        .body {
          text-align: center;
        }
        .img-box {
          margin: 20px 0;
        }
        #img {
           60%;
        }
      </style>
    </head>
    <body>
    
      <div class="body">
    
        <div class="input-box">
          <input id="input" type="file" accept="image/png, image/jpeg" onchange="onChangeInput()">
        </div>
    
        <div class="img-box">
          img:
          <img src="" alt="img" id="img">
        </div>
    
        <div class="canvas-box" id="canvas-box">
          canvas:
        </div>
    
      </div>
    
    
    <script>
      // 文件对象
      let file;
      // 文件 base64 码
      let fileDataURL;
    
    
      /**
       * @Date: 2020-11-25 10:32:51
       * @information: 获取文件
       */
      function onChangeInput() {
        file = document.getElementById('input').files[0]
        console.log('file->', file)
        if(!FileReader) {
          alert('浏览器版本过低,请升级版本')
          return;
        }
        fileToDataURL()
      }
    
      /**
       * @Date: 2020-11-25 10:31:47
       * @information: 使用 FileReader 读取文件内容, File(二进制) ——> dataURL(base64)   Blob ——> dataURL 同理
       */
      function fileToDataURL() {
        let reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = function(e) {
          console.log('dataURL->', reader.result)
          fileDataURL = reader.result
          showImg()
          dataURLToBlob()
        }
      }
    
      /**
       * @Date: 2020-11-25 10:33:13
       * @information: 图片回显
       */
      function showImg() {
        let img = document.getElementById('img')
        img.src = fileDataURL
      }
    
      /**
       * @Date: 2020-11-25 10:34:47
       * @information: dataURL(base64) ——> Blob(二进制)对象
       */
      function dataURLToBlob() {
        let arr = fileDataURL.split(','),
            mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]),
            n = bstr.length,
            u8arr = new Uint8Array(n);
        while(n --) {
          u8arr[n] = bstr.charCodeAt(n)
        }
        console.log('blob->', new Blob([u8arr], {type: mime}))
        fileAndBlobToCanvas()
        return new Blob([u8arr], {type: mime})
      }
    
      /**
       * @Date: 2020-11-25 10:53:31
       * @information: File, Blob 文件数据绘制到 canvas
       * 思路:File, Blob ——> dataURL ——> canvas
       */
      function fileAndBlobToCanvas() {
        let img = new Image()
        img.src = fileDataURL
        let canvas = document.createElement('canvas')
        if(!canvas.getContext) {
          alert('浏览器不支持canvas')
          return;
        }
        let ctx = canvas.getContext('2d')
        document.getElementById('canvas-box').appendChild(canvas)
        img.onload = function() {
          ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
          canvasToDataURL()
        }
      }
    
      /**
       * @Date: 2020-11-25 11:23:54
       * @information: 从 canvas 中获取文件 dataURL
       */
      function canvasToDataURL() {
        let canvas = document.createElement('canvas')
        let canvasDataURL = canvas.toDataURL('image/png', 1.0)
        console.log('从 canvas 中获取文件 dataURL :', canvasDataURL)
      }
    
    </script>
    
    </body>
    </html>
    
    





  • 相关阅读:
    3D有向包围盒与球体碰撞的算法
    搞笑段子,纪念我那逝去已久的大学生活
    [22] 计算几何图形包围盒与包围球的算法
    [21] Mesh法线的生成算法
    [20] 鼓状物(Drum)图形的生成算法
    [19] 半球形(Hemisphere)图形的生成算法
    [18] 螺旋楼梯(Spiral Stairs)图形的生成算法
    MySQL中MyISAM与InnoDB区别及选择,mysql添加外键
    在sublime3中docblockr插件配置apidoc接口文档注释模板
    sublime3 docblocker插件定制自己的注释,配置步骤
  • 原文地址:https://www.cnblogs.com/Faith-Yin/p/14036049.html
Copyright © 2011-2022 走看看