html5 canvas 图片压缩

var password, password_repeat;
        // 图片上传预览效果
        $scope.imgUp = {};      //用于存放图片的base64
        $scope.imgFlag = {idcardz:false,idcardf:false};
        $scope.userInfo = {};   //保存用户信息
        $scope.userInfoUp = {};
        $scope.payPassword = {};
        //用于压缩图片的canvas
        var canvas = document.createElement("canvas");
        var ctx = canvas.getContext('2d');
        //瓦片canvas
        var tCanvas = document.createElement("canvas");
        var tctx = tCanvas.getContext("2d");
        var maxsize = 100 * 1024;
        var formdata = getFormData();
        $scope.img_upload = function(objs) {       //单次提交图片的函数
          var doms = objs.name;
            var reader = new FileReader();
            //获取图片大小
            //~~   将数据转换成整形诗句
            var size = objs.files[0].size / 1024 > 1024 ? (~~(10 * objs.files[0].size / 1024 / 1024)) / 10 + "MB" : ~~(objs.files[0].size / 1024) + "KB";
            reader.onload = function() {
              var result = this.result;
              var img = new Image();
              img.src = result;
              $scope.$apply(function(){
                $scope.imgUp[doms] = {
                  imgSrc : result,  //接收base64
                };
                  $scope.imgFlag[doms] = true;
              });
                //如果图片大小小于100kb,则直接上传
                if (result.length <= maxsize) {
                  upload(result, objs.files[0].type, doms);
                  return;
                }
                //图片加载完毕之后进行压缩,然后上传
                if (img.complete) {
                  callback();
                } else {
                  img.onload = callback;
                }
                function callback() {
                  var data = compress(img);
                  upload(data, objs.files[0].type, doms);
                }
              };
              reader.readAsDataURL(objs.files[0]);
        };
        //使用canvas对大图片进行压缩
        function compress(img) {
          var initSize = img.src.length;
          var width = img.width;
          var height = img.height;
          //如果图片大于四百万像素,计算压缩比并将大小压至400万以下
          var ratio;
          if ((ratio = width * height / 4000000) > 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万则使用瓦片绘制
          var count;
          if ((count = width * height / 1000000) > 1) {
            count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片
            //计算每块瓦片的宽和高
            var nw = ~~(width / count);
            var nh = ~~(height / count);
            tCanvas.width = nw;
            tCanvas.height = nh;
            for (var i = 0; i < count; i++) {
              for (var j = 0; j < count; j++) {
                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);
          }
          //进行最小压缩
          var ndata = canvas.toDataURL('image/jpeg', 0.3);
          console.log('压缩前:' + initSize);
          console.log('压缩后:' + ndata.length);
          console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%");
          tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
          return ndata;
        }
        //图片上传,将base64的图片转成二进制对象,塞进formdata上传
        function upload(basestr, type, doms) {
          var text = window.atob(basestr.split(",")[1]);
          var buffer = new Uint8Array(text.length);
          var pecent = 0, loop = null;
          for (var i = 0; i < text.length; i++) {
            buffer[i] = text.charCodeAt(i);
          }
          var blob = getBlob([buffer], type);
          formdata.append(doms, blob);
        }
        /**
         * 获取blob对象的兼容性写法
         * @param buffer
         * @param format
         * @returns {*}
         */
        function getBlob(buffer, format) {
          try {
            return new Blob(buffer, {type: format});
          } catch (e) {
            var bb = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder);
            buffer.forEach(function(buf) {
              bb.append(buf);
            });
            return bb.getBlob(format);
          }
        }
        /**
         * 获取formdata
         */
        function getFormData() {
          var isNeedShim = ~navigator.userAgent.indexOf('Android')
              && ~navigator.vendor.indexOf('Google')
              && !~navigator.userAgent.indexOf('Chrome')
              && navigator.userAgent.match(/AppleWebKit\/(\d+)/).pop() <= 534;
          return isNeedShim ? new FormDataShim() : new FormData()
        }
        /**
         * formdata 补丁, 给不支持formdata上传blob的android机打补丁
         * @constructor
         */
        function FormDataShim() {
          console.warn('using formdata shim');
          var o = this,
              parts = [],
              boundary = Array(21).join('-') + (+new Date() * (1e16 * Math.random())).toString(36),
              oldSend = XMLHttpRequest.prototype.send;
          this.append = function(name, value, filename) {
            parts.push('--' + boundary + '\r\nContent-Disposition: form-data; name="' + name + '"');
            if (value instanceof Blob) {
              parts.push('; filename="' + (filename || 'blob') + '"\r\nContent-Type: ' + value.type + '\r\n\r\n');
              parts.push(value);
            }
            else {
              parts.push('\r\n\r\n' + value);
            }
            parts.push('\r\n');
          };
          // Override XHR send()
          XMLHttpRequest.prototype.send = function(val) {
            var fr,
                data,
                oXHR = this;
            if (val === o) {
              // Append the final boundary string
              parts.push('--' + boundary + '--\r\n');
              // Create the blob
              data = getBlob(parts);
              // Set up and read the blob into an array to be sent
              fr = new FileReader();
              fr.onload = function() {
                oldSend.call(oXHR, fr.result);
              };
              fr.onerror = function(err) {
                throw err;
              };
              fr.readAsArrayBuffer(data);
              // Set the multipart content type and boudary
              this.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
              XMLHttpRequest.prototype.send = oldSend;
            }
            else {
              oldSend.call(this, val);
            }
          };
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值