美文网首页
前端使用canvas对图片进行压缩

前端使用canvas对图片进行压缩

作者: 千茉紫依 | 来源:发表于2020-06-18 15:58 被阅读0次

    纯前端对图片压缩

    纯前端因为可以调用FileReader和canvas接口,在图片压缩方面非常便捷.思路就是获取图形数据后,找到相对比较短的边, 以他为基准压缩到一个比较小的比例(如640*480),图像的大小最终取决于三个因素:图片像素、编码质量和位深度,图形像素在执行完这条个函数之后就达到一个比较小的范围了,一般不会超过100k,而编码质量是一种类似于PS中表面模糊的效果,使用的是插值算法,一般编程80-90区间内可以对图像进行进一步的压缩,但是不建议压的太多,会失真。这里由于我们对图片大小有64k的严格限制,所以在对分辨率进行压缩之后,对编码质量又进行了一次压缩.

    在这里因为canvas绘出来的图形都是base64格式,base64是一种牺牲空间来换兼容性的编码,在编码中每三字节会扩充成四字节,这使得数据量会增加1/3,所以在计算图片大小时要除4/3,也就是乘0.75,这才是真正的图形数据

     compress(fileObj) {
          let reader = new FileReader();
          let that = this;
          reader.onload = function(e) {
            let image = new Image();
            image.src = e.target.result;
            image.onload = function() {
              let canvas = document.createElement('canvas');
              let context = canvas.getContext('2d');
              let imageWidth = image.width; //压缩后图片的大小
              let imageHeight = image.height;
              let data = '';
              let loopVar = imageWidth > imageHeight ? imageHeight : imageWidth;
              let compressRio = 0.9;
              let n = 0;
              //保证短边小于480
              while (loopVar >= 480) {
                loopVar = loopVar * compressRio;
                imageWidth = imageWidth * compressRio;
                imageHeight = imageHeight * compressRio;
                n++;
              }
              that.compressRio = compressRio * n;
              that.compressWidth = Math.floor(imageWidth);
              that.compressHeight = Math.floor(imageHeight);
              canvas.width = imageWidth;
              canvas.height = imageHeight;
    
              context.drawImage(image, 0, 0, imageWidth, imageHeight);
              data = canvas.toDataURL('image/jpeg', 0.85);
              //保证大小小于64K
                let imgSize = data.length *0.75 / 1024;
                let quatity = 0.85;
                while (imgSize > 64) {
                  quatity = quatity * compressRio;
                  data = canvas.toDataURL('image/jpeg', quatity);
                  imgSize = data.length *0.75 / 1024;
                }
               //压缩完成
            };
          };
          reader.readAsDataURL(fileObj);
        }
    

    用canvas压缩完成后此时得到的是base64编码的图片,可以在前端展示,但是要进行存储还是要转成二进制格式,转换函数如下

     convertBase64UrlToBlob(urlData) {
          //去掉url的头
          var arr = urlData.split(','),
            //获取后缀名
            mime = arr[0].match(/:(.*?);/)[1],
            //base64转换为byte
            bstr = atob(arr[1]),
            n = bstr.length,
            //新建无符号整形数组
            u8arr = new Uint8Array(n);
          while (n--) {
            //返回值的ascll编码
            u8arr[n] = bstr.charCodeAt(n);
          }
          return u8arr;
        }
    

    相关文章

      网友评论

          本文标题:前端使用canvas对图片进行压缩

          本文链接:https://www.haomeiwen.com/subject/sgmuxktx.html