2012-09-22 20 views
13

IOS6がリリースされました。写真のアップロードをテストしています。IOS6とSafari写真のアップロード - ファイルAPI + Canvas + jQuery Ajax非同期にファイルをアップロードしてサイズ変更する

これはうまくいきますが、3Gを超える大きな画像では期待どおりに動きません。

File APIとCanvasのおかげで、JavaScriptを使用して画像のサイズを変更することができます。画像をアップロードしようとする前に画像のサイズを変更すると、アップロードが速くなり、ユーザーの利便性が向上します。スマートフォンプロセッサがネットワークの速度よりも指数関数的に速く改善されているので、私はこのソリューションが勝者だと考えています。しかし、私はjQueryのアヤックスでそれを実装する最も困難な時間を過ごしてい

Image resize before upload

ニコラスは、画像リサイズのための優れたソリューションを提供してきました。このコードはおそらくIOS6以降のモバイルWebアプリケーション開発に非常に役立つだろうから、助言や助言があれば歓迎されます。

var fileType = file.type, 
    reader = new FileReader(); 

reader.onloadend = function() { 
    var image = new Image(); 
    image.src = reader.result; 

    image.onload = function() { 

     //Detect image size 
     var maxWidth = 960, 
      maxHeight = 960, 
      imageWidth = image.width, 
      imageHeight = image.height; 
     if (imageWidth > imageHeight) { 
      if (imageWidth > maxWidth) { 
       imageHeight *= maxWidth/imageWidth; 
       imageWidth = maxWidth; 
      } 
     } else { 
      if (imageHeight > maxHeight) { 
       imageWidth *= maxHeight/imageHeight; 
       imageHeight = maxHeight; 
      } 
     } 

     //Create canvas with new image 
     var canvas = document.createElement('canvas'); 
     canvas.width = imageWidth; 
     canvas.height = imageHeight; 
     var ctx = canvas.getContext("2d"); 
     ctx.drawImage(this, 0, 0, imageWidth, imageHeight); 

     // The resized file ready for upload 
     var finalFile = canvas.toDataURL(fileType); 

     if (formdata) { 

      formdata.append("images[]", finalFile); 

      $.ajax({ 
       url: "upload.php", 
       type: "POST", 
       data: formdata, 
       dataType: 'json', 
       processData: false, 
       contentType: false, 
       success: function (res) { 
        //successful image upload 
       } 
      }); 

     } 
    } 
} 
reader.readAsDataURL(file); 
+0

この問題に対する解決策をお探しですか?私は、大きな画像をカメラからまっすぐに、または過去にカメラから撮ったものをリサイズするときに、より問題があることを発見しました。 – NimmoNet

答えて

31

私はちょうどクライアント側のためのjQueryプラグインを開発しましたキャンバス画像のサイズ変更。 オリエンテーションiOS6スカッシュ画像も扱います。

あなたは試すことができます: http://gokercebeci.com/dev/canvasresize

使用法:

$.canvasResize(file, { 
       width : 300, 
       height : 0, 
       crop : false, 
       quality : 80, 
       callback: function(dataURL, width, height){ 

         // your code 

       } 
}); 
+1

これは素晴らしいです。もしできれば+10。私は数週間この作業をしています – TaylorMac

+0

http://camronjs.herokuapp.comキャンバスサイズ変更、websocketとajaxアップロードサファリのモバイルとブラウザ。 – chrisallick

7

私は、2回目のiOS6ベータ版以降、アップロード機能を使用しています。次のコードは、私の作品:

HTMLページの先頭でこれを入れて -

<script>window.onload = function() { 
var canvas = document.createElement('canvas'); 
var ctx = canvas.getContext("2d"); 

var fileSelect = document.getElementById("fileSelect"), 
    input = document.getElementById("input"); 

    input.addEventListener("change", handleFiles); 

    //hides ugly default file input button 
    fileSelect.addEventListener("click", function (e) { 
     if (input) { 
      input.click(); 
     } 
     e.preventDefault(); 
    }, false); 

function handleFiles(e) { 
    var reader = new FileReader; 
    reader.onload = function (event) { 
     var img = new Image(); 
     img.src = reader.result; 
     img.onload = function() { 
      var maxWidth = 320, 
       maxHeight = 350, 
       imageWidth = img.width, 
       imageHeight = img.height; 

      if (imageWidth > imageHeight) { 
       if (imageWidth > maxWidth) { 
        imageHeight *= maxWidth/imageWidth; 
        imageWidth = maxWidth; 
       } 
      } else { 
       if (imageHeight > maxHeight) { 
        imageWidth *= maxHeight/imageHeight; 
        imageHeight = maxHeight; 
       } 
      } 
      canvas.width = imageWidth; 
      canvas.height = imageHeight; 

      ctx.drawImage(this, 0, 0, imageWidth, imageHeight); 

      // The resized file ready for upload 
      var finalFile = canvas.toDataURL("image/png"); 

      var postData = 'canvasData=' + finalFile; 
      var ajax = new XMLHttpRequest(); 
      ajax.open('POST', 'save.php', true); 
      ajax.setRequestHeader('Content-Type', 'canvas/upload'); 

      ajax.onreadystatechange = function() { 
       if (ajax.readyState == 4) { 
        //just to visually confirm it worked... 
        window.open(canvas.toDataURL("image/png"), "mywindow"); 
       } 
      } 
      ajax.send(postData); 
     } 
    } 
    reader.readAsDataURL(e.target.files[0]); 
} 
} 
</script> 

ここではHTMLです -

<div style="width:320px;position:absolute;z-index:9;top:387px;"> 
<button style="width:60px;" id="fileSelect">upload</button> 
<input type="file" id="input" name="input" accept="image/*" style="display:none;"></div> 

がここにPHPだ -

<?php 
if (isset($GLOBALS["HTTP_RAW_POST_DATA"])) 
{ 
    // Get the data 
    $imageData=$GLOBALS['HTTP_RAW_POST_DATA']; 

    // Remove the headers (data:,) part. 
    // A real application should use them according to needs such as to check image type 
    $filteredData=substr($imageData, strpos($imageData, ",")+1); 

    // Need to decode before saving since the data we received is already base64 encoded 
    $unencodedData=base64_decode($filteredData); 

    // Save file. This example uses a hard coded filename for testing, 
    // but a real application can specify filename in POST variable 
    $fp = fopen('users/user_photo.png', 'wb'); 
    fwrite($fp, $unencodedData); 
    fclose($fp); 
} 
?> 

私が遭遇した唯一の問題は、90度回転させずに画像をカメラからロードすることです。

希望する場合は、コードに問題がある場合はお知らせください(私の最初の投稿です)。

+0

すばらしい。私はコードを使って作業し、90度回転の解決法を考え出すことができるかどうかを見ていきます。他の誰かがこれに対する解決策を持っていますか? – TaylorMac

+2

このソリューションは、カメラから撮影した写真でiPhone IO6で動作することがわかりました。私はこの方法を使用してサイズ変更された画像はすべて機能するが、画像は押しつぶされ、期待通りではないことがわかった。 – NimmoNet

+0

この実装を見てください。これは通常のOSではChrome上でうまく動作しますが、画像のサイズを変更するときにはIOS上で変わってしまいます。http://jsfiddle.net/Untd8/ – NimmoNet

1

我々は携帯電話のブラウザ上の大きな画像やメモリの問題を扱っているを考えると、私は軽量のソリューションができるかどうかを確認したかったです重複したキャンバスを作成したり、検出とサイズ変更のためだけに他のイメージ操作を実行することを避けることができます。

モバイルサファリが大きすぎる画像を縦方向に縮めたり、どれくらいの割合で同じ画像を残しているかのようです。私もキャンバスに画像をレンダリングする前にブラウザがモバイルのiDevice navigator.userAgent.match(/(iPod|iPhone|iPad)/) であれば、私は単にチェックすることにより

だから今、私は親指の非常に高速なルールを使用して...画像の高さまたは幅が2000ピクセルより大きい場合、その場合、それは押しつぶされることがわかります。 その場合、canvasContext.drawImage()には、イメージの高さを、指定したイメージサイズ変更の目的に対して、通常は4倍以上にすることを指定します。私が見たことに基づいて、Mobile Safariは画像を4倍に縮小します。

次に、画像をレンダリングし、最初に歪みのないレンダリングを行い、伸長された画像を元に戻します通常のX:Y比率。上記の100%解決策が使用されている追加のキャンバス要素またはコンテキストまたはテストレンダリングやピクセル反復を使用しないで、

私はいくつかのエッジケースがあり、イメージのサイズの制限が正確ではないかもしれないと確信していますが、私のアプリケーションでは、高速だったソリューションが欲しかったです。

関連する問題