

こんにちは。

monacaとニフティモバイルバックエンドを使ってアプリを作っています。  
フォトギャラリーを表示するアプリとそれを管理するアプリを作っています。

別の方が管理するアプリ側の画像をアップロードする部分を書いていたのですが、  
数MBあるスマホの画像をそのままアップロードするのでフォトギャラリー側での表示時に  
とても時間がかかり実用的ではありません。。

アップロードする前に画像の比率はそのままにリサイズしてアップロードできれば、、と思っています。

その他にも良い案があればご教授いただけると幸いです。  
以下がアップロードしているコードの一部です。

よろしくお願い致します。

[code]

       // 画像選択・カメラ起動
        $scope.showDialog = function(val) {
            if (val == 0) {
                // 画像を選択して取得
                var opt = {
                    quality: 50,
                    encodingType: Camera.EncodingType.JPEG,
                    destinationType: Camera.DestinationType.DATA_URL,
                    sourceType: Camera.PictureSourceType.PHOTOLIBRARY
                };
            } else {
                // 画像をカメラで撮って取得
                var opt = {
                    quality: 50,
                    encodingType: Camera.EncodingType.JPEG,
                    destinationType: Camera.DestinationType.DATA_URL,
                    sourceType: Camera.PictureSourceType.CAMERA
                };
            }
    
            navigator.camera.getPicture(onSuccess, onFail, opt);
        };
    
        function onSuccess(data) {
            $scope.img64 = data;
            document.getElementById('new_img').src = 'data:image/jpeg;base64,' + data;
        }
    
        function onFail() {
            // エラー
        }
    
        // 追加
        $scope.add = function() {
            if (document.getElementById('new_img').src != "images/no-image.png") {
                var file = toBlob($scope.img64);
                var fileNam = ImgBaseNam + no + ".jpg";
    
                var ncmbFile = new NCMB.File(fileNam, file);
    
                ncmbFile.save().then(function() {
                    // アップロード成功
                    var Obj = NCMB.Object.extend(imgClassNam);
                    var obj = new Obj();
    
                    var Today = new Date().toLocaleDateString();
    
                    obj.save(null, {
                        success: function(obj) {
    
                        alert("データを保存しました。");
    
                        },
                        error: function(obj, error) {
                            alert("データを保存に失敗しました。, error code: " + error.message);
                        }
                    });
                }, function(error) {
                    // アップロード失敗
                    alert(error.message);
                });
            }
        };
    
[/code]


CC BY-SA 3.0
2015-06-15T18:15:45.773
11378
2019-12-14T21:21:53.330
8389
question
javascript monaca
カメラで撮影した画像をリサイズしてアップロードしたい


HTML/JavaScript で画像データを縮小するには、`<canvas>`を利用する方法があります。  
Canvas に縮小サイズで描画した後、Canvas 自体を画像データとして取得する感じです。

動くデモ: <http://jsbin.com/bojowaseji/1/edit?html,output>

[code]

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>JS Bin</title>
    </head>
    <body>
      <input type="file" onchange="onInputChanged(event)">
      <hr>オリジナルサイズ:<br>
      <img id="previewLarge">
      <hr>縮小サイズ:<br>
      <img id="previewSmall">
      
      <script>
        function onInputChanged(e) {
          var file = e.target.files && e.target.files[0];
          if (file != null) {
            var reader = new FileReader();
            reader.onload = onImageLoad;
            reader.readAsDataURL(file);
          }
        }
        function onImageLoad(e) {
          var largeData = e.target.result;
          var smallData = makeSmall(largeData);
          previewLarge.src = largeData;
          previewSmall.src = smallData;
        }
        
        // 画像データ(DataURL)を縮小して返す
        function makeSmall(data) {
          // 画像データの縦横サイズを取得する
          var image = document.createElement('img');
          image.src = data;
          var width = image.naturalWidth;
          var height = image.naturalHeight;
    
          // 縮小する。今回は縦横それぞれ1/2
          var canvas = document.createElement('canvas');
          canvas.width = width / 2;
          canvas.height = height / 2;
          canvas.getContext("2d").drawImage(image, 0, 0, width / 2, height / 2);
          return canvas.toDataURL();
        }
      </script>
    </body>
    </html>
[/code]

サンプルコード:

[code]

    // 画像データ(DataURL)を縮小して返す
    function makeSmall(data) {
      // 画像データの縦横サイズを取得する
      var image = document.createElement("img");
      image.src = data;
      var width = image.naturalWidth;
      var height = image.naturalHeight;
    
      // 縮小する。今回は縦横それぞれ1/2
      var canvas = document.createElement("canvas");
      canvas.width = width / 2;
      canvas.height = height / 2;
      canvas.getContext("2d").drawImage(image, 0, 0, width / 2, height / 2);
    
      // データURLにして返す。他にバイナリを返す toBlob() メソッドもあります。
      return canvas.toDataURL();
      // JPEG形式のほうが良い圧縮率が得られると思われます。
      // 第2引数は品質レベルで、0.0~1.0の間の数値です。高いほど高品質。
      // return canvas.toDataURL("image/jpeg", 0.5);
    }
    
[/code]


CC BY-SA 4.0
2015-06-16T00:57:16.877
11386
2019-12-14T21:21:53.330
2019-12-14T21:21:53.330
32986
4809
11378
answer


mysticateaさん、信用度足りないので解答欄で(

toDataURLはデフォルトだと非圧縮png形式出力なので、容量低減目的であればjpeg出力をおすすめします。

[code]

    var png_img = canvas.toDataURL();
    var jpeg_img = canvas.toDataURL('image/jpeg');
    if( png_img.length > jpeg_img.length ){
     /*jpegの方が軽い*/
    }else{
     /*pngの方が軽い又はjpeg出力未対応でpng化された等*/
    }
    
[/code]


CC BY-SA 3.0
2015-06-16T08:59:16.497
11406
2015-06-16T08:59:16.497
9262
11378
answer