Skip to content

Latest commit

 

History

History
199 lines (171 loc) · 6.16 KB

02.md

File metadata and controls

199 lines (171 loc) · 6.16 KB

图片上传和下载

前言

以下操作例子 demo 源码地址 https://github.com/chenshenhai/canvas-note/tree/master/demo/image-processing/image-upload-download

上传显示

操作原理

  • 初始化一个隐藏的 input[type="file"] DOM
  • 触发 input[type="file"] 的点击事件去选取图片
  • 初始化一个文件读取器FileReader去读取input[type="file"] 得到的图片类文件数据Blob
  • 初始化一个img = new Image() 隐藏DOM, 等到 FileReader 读完数据将其base64字符串数据传入 img.src
  • 等待 img 加载完图片数据后,传入canvas的上下文绘制图片,context.drawImage 让图片显示出来

实现代码

/**
 * 图片文件数据流显示
 * @param {File} imageFile 图片类文件对象
 * @param {HTMLCanvasElement} canvas 画布document对象 
 */
function displayImage(imageFile, canvas) {
  // 初始化一个文件读取器
  const fileReader = new FileReader();

  // 设置文件读取结束事件
  fileReader.onload = function() {
    const img = new Image();
    // 将文件流的base64字符串数据 this.result 传入 图片对象 
    img.src = this.result;
    img.onload = function() {
      // 图片加载结束后
      // 将图片数据传入 canvas 的上下文context中
      canvas.width = img.width;
      canvas.height = img.height;
      const context = canvas.getContext('2d');
      context.drawImage(img, 0, 0, canvas.width, canvas.height)
    }
  };
  // 开始读取图片类文件对象内容
  // 读取结束后会文件对象以字符串格式传入 this.result 属性中
  fileReader.readAsDataURL(imageFile);
}

/**
 * 上传图片操作 uploadImage
 * @param {HTMLCanvasElement} canvas 画布document对象 
 */
function uploadImage(canvas) {
  // 初始化一个 input[type="file"] 的dom
  const inputFile = document.createElement('input');
  inputFile.type = 'file';
  // 设置变更事件
  inputFile.addEventListener('change', function() {
    const imageFile = this.files[0];
    if (!/\.(jpg|png)$/.test(imageFile.name)) {
      throw Errow('no image file!');
    }
    // 图片文件读取完毕后,将图片类文件数据显示在canvas上
    displayImage(imageFile, canvas);
  });
  // 出发文件读取的点击
  inputFile.click();
}

下载处理

操作原理

  • 将canvas的图片base64字符串数据取出
  • 初始化一个隐藏的<a> DOM,并设置连接为图片的字符串数据
  • 设置 <a> 的点击事件和下载文件名称
  • 触发点击

实现代码

/**
 * 下载图片操作 downloadImage
 * @param {string} filename 图片名称
 * @param {HTMLCanvasElement} canvas 画布document对象 
 */
function downloadImage(filename, canvas) {
  // 将canvas的图片字符串数据取出
  const stream = canvas.toDataURL("image/png");
  // 设置下载链接
  const downloadLink = document.createElement('a');
  downloadLink.href = stream;
  // 设置下载文件名称
  downloadLink.download = filename;
  // 设置点击事件
  const downloadClickEvent = document.createEvent('MouseEvents');
  // 出发点击事件
  downloadClickEvent.initEvent('click', true, false);
  downloadLink.dispatchEvent(downloadClickEvent);
}

完整操作实现

<button  id="J_Btn_Upload" >upload</button>
<button  id="J_Btn_Download" >download</button>
<canvas id="canvas-1"></canvas>
(function() {
  const canvas = document.getElementById('canvas-1');

  /**
   * 图片文件数据流显示
   * @param {File} imageFile 图片类文件对象
   * @param {HTMLCanvasElement} canvas 画布document对象 
   */
  function displayImage(imageFile, canvas) {
    // 初始化一个文件读取器
    const fileReader = new FileReader();

    // 设置文件读取结束事件
    fileReader.onload = function() {
      const img = new Image();
      // 将文件流的base64字符串数据 this.result 传入 图片对象 
      img.src = this.result;
      img.onload = function() {
        // 图片加载结束后
        // 将图片数据传入 canvas 的上下文context中
        canvas.width = img.width;
        canvas.height = img.height;
        const context = canvas.getContext('2d');
        context.drawImage(img, 0, 0, canvas.width, canvas.height)
      }
    };
    // 开始读取图片类文件对象内容
    // 读取结束后会文件对象以字符串格式传入 this.result 属性中
    fileReader.readAsDataURL(imageFile);
  }

  /**
   * 上传图片操作 uploadImage
   * @param {HTMLCanvasElement} canvas 画布document对象 
   */
  function uploadImage(canvas) {
    // 初始化一个 input[type="file"] 的dom
    const inputFile = document.createElement('input');
    inputFile.type = 'file';
    // 设置变更事件
    inputFile.addEventListener('change', function() {
      const imageFile = this.files[0];
      if (!/\.(jpg|png)$/.test(imageFile.name)) {
        throw Errow('no image file!');
      }
      // 图片文件读取完毕后,将图片类文件数据显示在canvas上
      displayImage(imageFile, canvas);
    });
    // 出发文件读取的点击
    inputFile.click();
  }

  /**
   * 下载图片操作 downloadImage
   * @param {string} filename 图片名称
   * @param {HTMLCanvasElement} canvas 画布document对象 
   */
  function downloadImage(filename, canvas) {
    // 将canvas的图片字符串数据取出
    const stream = canvas.toDataURL("image/png");
    // 设置下载链接
    const downloadLink = document.createElement('a');
    downloadLink.href = stream;
    // 设置下载文件名称
    downloadLink.download = filename;
    // 设置点击事件
    const downloadClickEvent = document.createEvent('MouseEvents');
    // 出发点击事件
    downloadClickEvent.initEvent('click', true, false);
    downloadLink.dispatchEvent(downloadClickEvent);
  }


  const btnUpload = document.getElementById('J_Btn_Upload');
  const btnDownload = document.getElementById('J_Btn_Download');

  btnUpload.addEventListener('click', function() {
    uploadImage(canvas);
  });
  btnDownload.addEventListener('click', function() {
    downloadImage('download-image.png', canvas);
  });

})();