H5 调用本地相机并压缩上传(是从angular的ionic项目中截取的)

html部分

 1   <div class="list_upload item bg_white">
 2     <div class="itemImg pic_upload" ng-repeat="item in thumb">
 3         <!-- 采用angular循环的方式,对存入thumb的图片进行展示 -->
 4           <img ng-src="{{item.imgSrc}}" alt=""/>
 5           <span class="itemImgClose" ng-if="item.imgSrc" ng-click="img_del($index)"><i class="ion-android-close"></i></span>
 6       </div>
 7       <div class="item_file" ng-repeat="item in thumb_default" ng-if="addImg">
 8            <!-- 这里之所以写个循环,是为了后期万一需要多个‘加号’框 -->
 9            <div class="item pic_upload"> <i class="icon ion-android-add"></i>
10              添加图片<input type="file" id="one-input"  accept="image/*" file-model="images" onchange="angular.element(this).scope().img_upload(this.files)"/>
11          </div>
12      </div>
13  </div>

js部分

      $scope.reader = new FileReader();   //创建一个FileReader接口
      $scope.thumb = {};      //用于存放图片的base64
      $scope.imagNmae = [];
      //监听照片的变化
      console.log($scope.thumb);
      $scope.thumb_default = {    //用于循环默认的‘加号’添加图片的框
        1111:{}
      };
      //用于压缩图片的canvas
      var canvas = document.createElement("canvas");
      var ctx = canvas.getContext('2d');
      //瓦片canvas
      var tCanvas = document.createElement("canvas");
      var tctx = tCanvas.getContext("2d");
      //ionic post请求头部
      var transFn = function (obj) {
          return $httpParamSerializerJQLike(obj);
        },
        postCfg = {
          headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
          transformRequest:transFn
        };
      var flag = 0; //标志位
      $scope.addImg = true;
      var maxSize = 100*1024; //图片大小为100kb
      $scope.img_upload = function(files) {       //单次提交图片的函数
        flag++;
        var size = files[0].size / 1024 > 1024 ? (~~(10 * files[0].size / 1024 / 1024)) / 10 + "MB" : ~~(files[0].size / 1024) + "KB";
        $scope.guid = (new Date()).valueOf();   //通过时间戳创建一个随机数,作为键名使用
        $scope.reader.readAsDataURL(files[0]);  //FileReader的方法,把图片转成base64
        $scope.reader.onload = function (ev) {
          $scope.$apply(function () {
            $scope.thumb[$scope.guid] = {
              imgSrc: ev.target.result,  //接收base64
            }
          });
          //上传图片的调用
          var result = this.result;
          var img = new Image();
          img.src = result;
          if (result.length <= maxSize) {
            upload(result, files[0].type);
            return;
          }
          //图片加载完毕之后进行压缩,然后上传
          if (img.complete) {
            callback();
          } else {
            img.onload = callback;
          }
          function callback() {
            var data = compress(img);
            upload(data, files[0].type);
            img = null;
          }
        };
        //判断图片的数量
        if(flag >= 3){
          $scope.addImg = false;
        }
      };

      $scope.img_del = function(key) {    //删除,删除的时候thumb和form里面的图片数据都要删除,避免提交不必要的
        flag--;
        console.log(key);
        var guidArr = [],ImgId = [];
        for(var p in $scope.thumb){
          guidArr.push(p);
        }
        delete $scope.thumb[guidArr[key]]; //删除图片
        for(var s in $scope.imagNmae){
          ImgId.push(s);
        }
        delete $scope.imagNmae[ImgId[key]]; //删除图片id
        if(flag < 3){
          $scope.addImg = true;
        }
      };

       //使用canvas对大图片进行压缩
      var compress = function(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.1);
        //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;
      };
     //图片上传,
      var upload = function (basestr,type) {
        var text = basestr.split(",")[1]; //截取图片字节流
        var obj = {
          "参数名":"参数"
        };
        $http.post("接口链接",obj,postCfg).success(function (data) {
          
        }).error(function(err){
          $scope.loadMore = true;
          $ionicLoading.show({
            template: "无法加载数据。请稍后再试。",
            duration: 2000
          });
        });
      };

效果展示

 

参考友情链接:

1、https://github.com/whxaxes/node-test/blob/master/server/upload/index_2.html

2、https://github.com/whxaxes/node-test/blob/master/server/upload/upload_2.js

3、http://www.cnblogs.com/jach/p/5734920.html

转载于:https://www.cnblogs.com/vitucu/p/7600438.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值