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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM