2012-09-22 4 views
13

IOS6이 출시되었으며 사진 업로드를 테스트 해 왔습니다.IOS6 및 Safari 사진 업로드 - 파일 API + 캔버스 + jQuery Ajax 비동기식으로 파일 업로드 및 크기 조정

잘 작동하지만 3G를 초과하는 큰 이미지의 경우 예상대로 느립니다.

File API 및 Canvas 덕분에 JavaScript를 사용하여 이미지의 크기를 조정할 수 있습니다. 업로드하기 전에 이미지의 크기를 조정하면 업로드 속도가 빨라지므로 빠른 사용자 경험을 제공 할 수 있기를 바랍니다. 스마트 폰 프로세서가 네트워크 속도보다 기하 급수적으로 빠르게 향상되면서 나는이 솔루션이 승자라고 믿습니다.

니콜라스 이미지 크기 조정을위한 우수한 솔루션을 제공하고있다 :

Image resize before upload

는 그러나, 나는 jQuery의 아약스를 구현하는 힘든 시간을 보내고 있어요. 이 코드는 IOS6 이후의 모바일 웹 애플리케이션 개발에 매우 ​​유용하기 때문에 조언이나 도움을 받으실 수 있습니다.

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 및 아약스 사파리 모바일 및 브라우저 업로드 업로드되었습니다. – chrisallick

7

두 번째 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의 -

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

- 여기

<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의 내가 앓은 유일한 문제는 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 pix보다 큰 경우, 나는 그것이 부숴 질 것이라는 것을 안다. 그럴 경우 canvasContext.drawImage()에서 이미지 높이를 지정된 이미지 크기 조정 목표에 대해 보통 4 배가되어야한다고 지정합니다. 내가 본 것을 바탕으로 모바일 사파리는 이미지를 4 배로 축소합니다.

그런 다음 이미지를 렌더링하고 왜곡되지 않은 상태로 처음 렌더링합니다. 그러면 미리 늘린 이미지가 다시 그 다음으로 축소됩니다. 정상적인 X : Y 비율. 위에 언급 된 100 % 솔루션이 사용하는 추가 캔버스 요소 나 컨텍스트 또는 테스트 렌더 또는 픽셀 반복 없이는 사용합니다.

몇 가지 엣지 케이스가있을 수 있으며 이미지 크기 제한이 정확하지 않을 수도 있지만 내 앱의 경우 빠름 해결책을 원했습니다.