• 图片上传压缩校正


    import Exif from 'exif-js';
    /* eslint-disable func-names */
    function ImageProcess(file, callback) {
      let Orientation;
      // 去获取拍照时的信息,解决拍出来的照片旋转问题
      Exif.getData(file, function () {
        Orientation = Exif.getTag(this, 'Orientation');
      });
      // console.log("Orientation", Orientation);
      // 看支持不支持FileReader
      if (!file || !window.FileReader) return;
      if (/^image/.test(file.type)) {
        // 创建一个reader
        const reader = new window.FileReader();
        // 将图片2将转成 base64 格式
        reader.readAsDataURL(file);
        // 读取成功后的回调
        reader.onloadend = function () {
          const img = new window.Image();
          img.src = this.result;
          img.onload = function () {
            // 压缩图片
            const data = ImageCompress(img, Orientation);
            // console.log(dataURItoBlob(data));
            callback(data);
          };
        };
      }
    }
    function ImageCompress(img, Orientation) {
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      // 瓦片canvas
      const tCanvas = document.createElement('canvas');
      const tctx = tCanvas.getContext('2d');
      let { width, height } = img;
    
      // 如果图片大于四百万像素,计算压缩比并将大小压至400万以下
      let ratio = (width * height) / 4000000;
      if (ratio > 1) {
        ratio = Math.sqrt(ratio);
        width /= ratio;
        height /= ratio;
      } else {
        ratio = 1;
      }
      canvas.width = width;
      canvas.height = height;
      // 铺底色
      ctx.fillStyle = '#fff';
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      // 如果图片像素大于100万则使用瓦片绘制
      let count = (width * height) / 1000000;
      if (count > 1) {
        // 计算要分成多少块瓦片
        count = ~~(Math.sqrt(count) + 1);
        // 计算每块瓦片的宽和高
        const nw = ~~(width / count);
        const nh = ~~(height / count);
        tCanvas.width = nw;
        tCanvas.height = nh;
        for (let i = 0; i < count; i += 1) {
          for (let j = 0; j < count; j += 1) {
            tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
            ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
          }
        }
      } else {
        ctx.drawImage(img, 0, 0, width, height);
      }
      // 修复ios上传图片的时候 被旋转的问题
      if (Orientation && Orientation !== 1) {
        switch (Orientation) {
          case 6: // 需要顺时针(向左)90度旋转
            rotateImg(img, 'left', canvas);
            break;
          case 8: // 需要逆时针(向右)90度旋转
            rotateImg(img, 'right', canvas);
            break;
          case 3: // 需要180度旋转 转两次
            rotateImg(img, 'right', canvas);
            rotateImg(img, 'right', canvas);
            break;
          default: break;
        }
      }
      // 进行最小压缩
      const ndata = canvas.toDataURL('image/jpeg', 0.5);
      // 清除canvas画布的宽高
      tCanvas.width = 0;
      tCanvas.height = 0;
      canvas.width = 0;
      canvas.height = 0;
      // 打印压缩前后的大小,以及压缩比率
      // const initSize = img.src.length;
      // console.log('压缩前:' + initSize);
      // console.log('压缩后:' + ndata.length);
      // console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%");
      // console.log(ndata);
      return ndata;
    }
    
    function rotateImg(img, direction, cvs) {
      const canvas = cvs;
      // 最小与最大旋转方向,图片旋转4次后回到原方向
      const minStep = 0;
      const maxStep = 3;
      if (img == null) return;
      // img的高度和宽度不能在img元素隐藏后获取,否则会出错
      const { width, height } = img;
      let step = 2;
      if (step == null) {
        step = minStep;
      }
      if (direction === 'right') {
        step += 1;
        // 旋转到原位置,即超过最大值
        if (step > maxStep) step = minStep;
      } else {
        step -= 1;
        if (step < minStep) step = maxStep;
      }
      // 旋转角度以弧度值为参数
      const degree = (step * 90 * Math.PI) / 180;
      const ctx = canvas.getContext('2d');
      switch (step) {
        case 0:
          canvas.width = width;
          canvas.height = height;
          ctx.drawImage(img, 0, 0);
          break;
        case 1:
          canvas.width = height;
          canvas.height = width;
          ctx.rotate(degree);
          ctx.drawImage(img, 0, -height);
          break;
        case 2:
          canvas.width = width;
          canvas.height = height;
          ctx.rotate(degree);
          ctx.drawImage(img, -width, -height);
          break;
        case 3:
          canvas.width = height;
          canvas.height = width;
          ctx.rotate(degree);
          ctx.drawImage(img, -width, 0);
          break;
        default: break;
      }
    }
    function dataURItoBlob(dataURI) {
      const byteString = window.atob(dataURI.split(',')[1]);
      const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
      // const ab = new ArrayBuffer(byteString.length);
      const ia = new Uint8Array(byteString.length);
      for (let i = 0; i < byteString.length; i += 1) {
        ia[i] = byteString.charCodeAt(i);
      }
      return new window.Blob([ia], { type: mimeString });
    }
    export default ImageProcess;
    import Exif from 'exif-js';
    /* eslint-disable func-names */
    function ImageProcess(file, callback) {
    let Orientation;
    // 去获取拍照时的信息,解决拍出来的照片旋转问题
    Exif.getData(file, function () {
    Orientation = Exif.getTag(this, 'Orientation');
    });
    // console.log("Orientation", Orientation);
    // 看支持不支持FileReader
    if (!file || !window.FileReader) return;
    if (/^image/.test(file.type)) {
    // 创建一个reader
    const reader = new window.FileReader();
    // 将图片2将转成 base64 格式
    reader.readAsDataURL(file);
    // 读取成功后的回调
    reader.onloadend = function () {
    const img = new window.Image();
    img.src = this.result;
    img.onload = function () {
    // 压缩图片
    const data = ImageCompress(img, Orientation);
    // console.log(dataURItoBlob(data));
    callback(data);
    };
    };
    }
    }
    function ImageCompress(img, Orientation) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    // 瓦片canvas
    const tCanvas = document.createElement('canvas');
    const tctx = tCanvas.getContext('2d');
    let { width, height } = img;

    // 如果图片大于四百万像素,计算压缩比并将大小压至400万以下
    let ratio = (width * height) / 4000000;
    if (ratio > 1) {
    ratio = Math.sqrt(ratio);
    width /= ratio;
    height /= ratio;
    } else {
    ratio = 1;
    }
    canvas.width = width;
    canvas.height = height;
    // 铺底色
    ctx.fillStyle = '#fff';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    // 如果图片像素大于100万则使用瓦片绘制
    let count = (width * height) / 1000000;
    if (count > 1) {
    // 计算要分成多少块瓦片
    count = ~~(Math.sqrt(count) + 1);
    // 计算每块瓦片的宽和高
    const nw = ~~(width / count);
    const nh = ~~(height / count);
    tCanvas.width = nw;
    tCanvas.height = nh;
    for (let i = 0; i < count; i += 1) {
    for (let j = 0; j < count; j += 1) {
    tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
    ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
    }
    }
    } else {
    ctx.drawImage(img, 0, 0, width, height);
    }
    // 修复ios上传图片的时候 被旋转的问题
    if (Orientation && Orientation !== 1) {
    switch (Orientation) {
    case 6: // 需要顺时针(向左)90度旋转
    rotateImg(img, 'left', canvas);
    break;
    case 8: // 需要逆时针(向右)90度旋转
    rotateImg(img, 'right', canvas);
    break;
    case 3: // 需要180度旋转 转两次
    rotateImg(img, 'right', canvas);
    rotateImg(img, 'right', canvas);
    break;
    default: break;
    }
    }
    // 进行最小压缩
    const ndata = canvas.toDataURL('image/jpeg', 0.5);
    // 清除canvas画布的宽高
    tCanvas.width = 0;
    tCanvas.height = 0;
    canvas.width = 0;
    canvas.height = 0;
    // 打印压缩前后的大小,以及压缩比率
    // const initSize = img.src.length;
    // console.log('压缩前:' + initSize);
    // console.log('压缩后:' + ndata.length);
    // console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%");
    // console.log(ndata);
    return ndata;
    }

    function rotateImg(img, direction, cvs) {
    const canvas = cvs;
    // 最小与最大旋转方向,图片旋转4次后回到原方向
    const minStep = 0;
    const maxStep = 3;
    if (img == null) return;
    // img的高度和宽度不能在img元素隐藏后获取,否则会出错
    const { width, height } = img;
    let step = 2;
    if (step == null) {
    step = minStep;
    }
    if (direction === 'right') {
    step += 1;
    // 旋转到原位置,即超过最大值
    if (step > maxStep) step = minStep;
    } else {
    step -= 1;
    if (step < minStep) step = maxStep;
    }
    // 旋转角度以弧度值为参数
    const degree = (step * 90 * Math.PI) / 180;
    const ctx = canvas.getContext('2d');
    switch (step) {
    case 0:
    canvas.width = width;
    canvas.height = height;
    ctx.drawImage(img, 0, 0);
    break;
    case 1:
    canvas.width = height;
    canvas.height = width;
    ctx.rotate(degree);
    ctx.drawImage(img, 0, -height);
    break;
    case 2:
    canvas.width = width;
    canvas.height = height;
    ctx.rotate(degree);
    ctx.drawImage(img, -width, -height);
    break;
    case 3:
    canvas.width = height;
    canvas.height = width;
    ctx.rotate(degree);
    ctx.drawImage(img, -width, 0);
    break;
    default: break;
    }
    }
    function dataURItoBlob(dataURI) {
    const byteString = window.atob(dataURI.split(',')[1]);
    const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
    // const ab = new ArrayBuffer(byteString.length);
    const ia = new Uint8Array(byteString.length);
    for (let i = 0; i < byteString.length; i += 1) {
    ia[i] = byteString.charCodeAt(i);
    }
    return new window.Blob([ia], { type: mimeString });
    }
    export default ImageProcess;
  • 相关阅读:
    Hibernate官方文档翻译-(第二章,入门)
    关于我的Blog
    退役记
    考场上要写的emacs
    关于在linux下将caps lock键改成ctrl的方法
    SXOI2020退役记
    min_25筛学习笔记
    带花树学习笔记
    [CF438E] 小朋友和二叉树
    多项式中步
  • 原文地址:https://www.cnblogs.com/shangyueyue/p/10094812.html
Copyright © 2020-2023  润新知