不通过 上传文件图片到服务器

在浏览器中操作文件,多数情况下用到的是 File 对象,从 元素获取,进而继续操作(例如将选择的图片展示在页面上,用ajax将文件上传至服务器等)。这里介绍在HTTP获取图片URL创建图片,canvas拼接文字,上传到服务器。

一、canvas获取dataURL

/**
 * 根据二维码画canvas合成文字
 * @param {string} src  二维码图片路径
 * @param {string} text  拼接的二维码文字
 * @return {string} src 合成后的图片地址
 */
export async function drawImage(src, text) {
  const img = await createImg(src);
  const canvas = document.createElement('canvas');
  let context = canvas.getContext('2d');
  // 确保canvas的尺寸和图片一样
  const width = img.width;
  const height = img.height;
  canvas.width = img.width;
  canvas.height = img.height + 50;
  context.drawImage(img, 0, 0, width, height);
  context.fillStyle = '#FFF';
  context.fillRect(0, img.height, width, 50);
  const font = '20px Arial bolder';
  context.font = font;
  context.fillStyle = 'black';
  context.fillText(text, width / 2 - (context.measureText(font).width / 2), img.height + 29);
  let url = canvas.toDataURL();
  // canvas 转为blob类型 可直接传入file
  // canvas.toBlob((blob) => {
  //   console.log(blob);
  //   var myFile = new File([blob], 'aa.png', {
  //     type: 'mime'
  //   });
  // });
  return url;
}
/**
 * 创建图片
 * @param {string} src 被创建图片的src或者base64
 * @return {Promise.}
 */
function createImg(src) {
  return new Promise((resolve, reject) => {
    let image = new Image();
    image.crossOrigin = 'anonymous';
    image.onload = () => {
      resolve(image);
    };
    image.onerror = () => {
      reject({
        errStr: '图片加载失败,请重试'
      });
      console.log('图片加载失败,请重试');
    };
    image.src = src;
  });
}

二、二进制数据容器

  • blob:适用于读取二进制数据,比如图片文件

    • 表示不可变、原始数据的类文件对象(js都不一定认得)
    • blob更偏重于整体操作(整个文件的二进制流)
  • ECMAScript二进制数组 按照数组的方式处理二进制数据

    • js可以识别的二进制数据
  • 可以做流的切割,所有注重于对二进制流中的字节进行处理

1. 第一种方式

我第一次采取的方法利用canvas的todataurl方法获取dataurl后 :拿到dataurl后获取逗号后面的编码数据利用window.atob将编码解码,将解码后的字符串使用charcodeat获取每一个字符串的unicode字符,然后存入Uint8Array数组,创建文件对象,放入form表单中上传到服务器。

dataURL是base64编码的数据格式
(将 dataURL 转为 blob对象:网上有用new Blob([u8arr], { type: mime }); 把Uint8Array转为blob,再后续操作也可以,我给省去了)

/**
 * 将base64转换为文件
 * @param {string} apiUrl 服务器地址
 * @param {string} dataurl url
 * @param {string} imageName 图片名字
 * @return {Object} response 文件信息
 */
export function dataURLtoFile(apiUrl, dataurl, imageName) {
  // 将base64转换为文件流
  const arr = dataurl.split(',');
  // 获取逗号后面的编码数据利用window.atob将编码解码
  const mime = arr[0].match(/:(.*?);/)[1];
  const bstr = atob(arr[1]);
  // 解码后的字符串使用charcodeat获取每一个字符串的unicode字符
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  // 存入Uint8Array数组 创建文件对象
  var myFile = new File([u8arr], imageName, {
    type: mime
  });
  var formData = new FormData();
  // 将文件转二进制
  formData.append('file', myFile);
  let config = {
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  };
  // 通过axios将图片上传至服务器
  return new Promise((resolve, reject) => {
    axios.post(apiUrl, formData, config).then(res => {
      const response = res.data;
      if (response && response.errNo === 0) {
        const {
          data
        } = response;
        resolve(data);
      }
      else {
        reject(response.errstr);
      }
    })
      .catch(err => {
        reject(err);
        console.log(err);
      });
  });
}
  1. 第二种方法

后整理时发现file对象要求传入的文件内容也可以是Blob,想到canvas也可以转为blob对象

image

于是就测试了canvas不用toDataURL(),用toBlob()直接把blob传入new file()中,这样代码简略了很多

var blob = canvas.toBlob((blob) => {
    console.log(blob);
    var myFile = new File([blob], 'aa.png', {
      type: 'mime'
    });
    console.log(myFile);
  });

对比结果

-第一种方式的file对象

image.png

-第二种的blob 和file对象

image

这是测试上传到我本地自建的服务器中,是一样的,size少了1 ,忽略掉图片名字和后缀,测试写死了, 正常都应是动态传进来的

image

再提供几个常用的转换参考

blob转dataUrl:

用途:拿到blob对象后,希望展示这个数据

用法:使用window.URL.createObjectURL(blob)拿到dataUrl对象,然后进行展示

canvan转blob:canvas 最新的方法 toblob

canvas转dataurl:canvas的实例方法 todataurl

blob转canvas:blob转换为dataurl对象后 新疆一个图片用来显示dataurl数据,然后将图片放入canvas中

dataurl转canvas:dataurl先变成图片再放入canvas

img转canvas:canvas的drawImage方法支持将img放入canvas

canvas转img:利用canvas的todataurl方法获取图片数据后,新建图片控件展示图片

萌新记录 欢迎大佬指点

你可能感兴趣的:(不通过 上传文件图片到服务器)