2012-09-22 21 views
13

IOS6 piyasaya sürüldü ve ben fotoğraf yüklemeyi test ediyorum.IOS6 ve Safari Photo Uploading - Dosya API + Canvas + jQuery Ajax Dosyaları Eşzamansız Yükleme ve Yeniden Boyutlandırma

İyi çalışıyor, ancak 3G üzerinde daha büyük resimlerle beklendiği gibi YAVAŞ.

Dosya API'sı ve Canvas sayesinde, resimleri JavaScript kullanarak yeniden boyutlandırmak mümkündür. Fotoğrafları yüklemeyi denemeden önce yeniden boyutlandırırsam, daha hızlı bir kullanıcı deneyimine sahip olmak için daha hızlı yüklerler. Akıllı telefon işlemcileri, ağ hızlarından katlanarak daha hızlı ilerlerken, bu çözümün bir kazanan olduğuna inanıyorum.

Nicolas resim boyutlandırma için mükemmel bir çözüm getirmiştir:

Image resize before upload

Ancak, jQuery'nin Ajax ile uygulamadan en zor zaman yaşıyorum. Herhangi bir öneri veya yardım, bu kod muhtemelen mobil web uygulaması geliştirme sonrası IOS6 için son derece yararlı olacağı için takdir edilmektedir.

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

Bunun için bir çözüm buldunuz mu? Büyük resimleri doğrudan kameradan yeniden boyutlandırırken ya da geçmişte kameradan çekilen bir fotoğrafta daha sorunlu olduğunu fark ettim. – NimmoNet

cevap

31

İstemci tarafı için bir jQuery eklentisi geliştirdim kanvas image resizing. Ayrıca yönlendirmesi ve iOS6 sıkıştırılmış görüntü sorununu işler.

Deneyebilirsin: http://gokercebeci.com/dev/canvasresize

Kullanımı:

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

         // your code 

       } 
}); 
+1

bu harika. Yapabilseydim +10. Ben bu hafta üzerinde çalışıyorum – TaylorMac

+0

http://camronjs.herokuapp.com tuval yeniden boyutlandırma, websocket ve ajax upload safari mobil ve tarayıcı. – chrisallick

7

İkinci iOS6 beta sürümünden bu yana yükleme özelliği ile çalışıyorum. Aşağıdaki kod benim için çalışıyor: HTML sayfanızın kafasında

Put bu - İşte

<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 var -

<?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); 
} 
?> 

- İşte

<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 bulunuyor Mücadelediğim tek sorun, 90 derece döndürmeden kameradan resim yüklenmesini sağlamak.

Bu yardımcı olur, bana koduyla ilgili herhangi bir sorun yaşarsanız bildirin (bu benim ilk gönderimim).

+0

Fantastik. Kodla çalışacağım ve 90 derece rotasyon için bir çözüm bulabilir miyim diye bakacağım. Bunun için başka bir çözüm var mı? – TaylorMac

+2

Fotoğraf makinesinden çekilen resimlerle iPhone IO6 üzerinde çalışmak için bu çözümü buldunuz. Bu yöntem kullanılarak yeniden boyutlandırılan görüntülerin çalıştığını ancak görüntünün beklendiği gibi değil, ezildiğini buldum. – NimmoNet

+0

Bu uygulamaya bir göz atın. Bu, normal bir işletim sistemi üzerinde Chrome'da gayet iyi çalışıyor ancak görüntüyü yeniden boyutlandırırken IOS üzerinde garip bir şey var. Http://jsfiddle.net/Untd8/ – NimmoNet

1

biz bir mobil tarayıcıda büyük resimler ve hafıza sorunları ile uğraşıyoruz göz önüne alındığında, bir hafif çözümü can görmek istedim Yinelenen bir tuval oluşturulmasını ve yalnızca görüntülenmesi ve yeniden boyutlandırılması için diğer görüntü işlemlerinin yapılmasını önleyen bir özellik bulunmalıdır.

Mobil Safari dikey olarak çok büyük bir görüntüyü sıkıştırırsa, ne kadar orana sahip olduğu, oran aynı kalırsa görünür. tarayıcı mobil İDevice navigator.userAgent.match(/(iPod|iPhone|iPad)/) olup olmadığını basitçe kontrol sayede

Bu yüzden şu anda bile tuval üzerine resmi işlemek önce, baş parmak çok hızlı bir kural kullanabilirsiniz ...VE görüntü yüksekliği veya genişliği 2000 pikselden daha büyüktür, bu durumda bunun ezileceğini biliyorum. Bu durumda, canvasContext.drawImage() içinde, görüntü yüksekliğini, normal bir görüntü yeniden boyutlandırma hedefi için normalde olması gerekenden 4 kat daha uzun olacak şekilde belirtirim. Gördüğüm şeyden hareketle, Mobile Safari görüntüyü 4 kat artırıyor.

SONRA Görüntüyü oluşturuyorum ve daha sonra ilk önce, önceden gerilmiş bir görüntüyü daha sonra ne hale getireceğine kararsızlaştırıyor. normal X: Y oranı. Yukarıda belirtilen% 100 çözümün ek tuval öğeleri veya bağlamları veya test oluşturma veya piksel yinelemeleri olmadan kullanır.

Bazı kenar kutuları olabileceğinden ve görüntü boyutu sınırının tam olabileceğinden emin olabilirim, ancak uygulama için HIZLI bir çözüm istedim.