2011-10-14 2 views
9

html5 캔버스의 내용을 가져와 내 장고 서버에 전달하려고합니다. 그러면 내 장고 서버로 전달되어 PNG로 조작되고 PNG로 저장됩니다. 여기에 내가 가지고있는 것들이있다 :Django로 PIL 이미지에 html5 캔버스로드

HTML 폼에서 사용자가 "업데이트"버튼을 클릭하면 캔버스의 내용 - canvas.toDataURL() -이 POST 폼을 통해 제출 된 텍스트 상자에 덤프된다. . 결국 이것은 자동이지만 현재는 그렇지 않습니다.

<input type="text" id="canvasData" name="canvasData"/> 
<input type='button' value="update" onclick='jscript:updateData();'> 
<canvas id="sketch"></canvas> 
<script type="text/javascript"> 
    function jscript:updateData() { 
     $('#canvasData')[0].value = $('canvas')[0].toDataURL(); 
    } 
</script> 

canvasData는 형태 인 '데이터 : 이미지/PNG;베이스 64, ... 등 ... iVBORw0KGgoAAAA ='이를 통해 전송 될때. 그럼 내가 장고에서 처리해 :

from PIL import Image 
... 
canvasData = request.POST.get('canvasData', '') 
im = Image.somehowLoad(canvasData) 
... 
im.save('canvas.png') 

그리고 이것은 내가 갇혀있다. base64로 인코딩 된 데이터 URL을 사용하여 이미지를 PIL로 사용 가능한 형식으로로드하는 방법을 알아낼 수 없습니다.

감사합니다.

편집 : 여기 하단 주석에 대한 코드는 다음과 같습니다

>>> d 
'data:image/png;base64,iVBORw0K' 
>>> d.strip('data:image/png;base64,') 
'VBORw0K' 

답변

18
import re 

datauri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==' 

imgstr = re.search(r'base64,(.*)', datauri).group(1) 

output = open('output.png', 'wb') 

output.write(imgstr.decode('base64')) 

output.close() 

하거나 PIL로로드해야하는 경우 :

import cStringIO 

tempimg = cStringIO.StringIO(imgstr.decode('base64')) 

im = Image.open(tempimg) 
+0

내가 잘못된 패딩 예외 때 받고 있어요 .decode()를 사용합니다. 문자열의 시작 부분에서 '데이터 : 이미지 ...'중 일부를 제거해야합니까? 나는 그것에 다른 변이를 시도하고 도움이되지 않았다. – wizpig64

+0

데이터 URI에서 base64로 인코딩 된 데이터를 가져 오는 간단한 정규식으로 내 대답을 업데이트했습니다. – Acorn

+0

나는 지금 내 솔루션에 무엇이 잘못되었는지 알아 냈다. 파이썬은 내가 의도 한 것보다 하나의 여분의 문자를 제거하고있다. (왜 그런지 알고 싶습니까?) 도움을 많이 주셔서 감사합니다. 나는이 버전보다 두통이 적 으면서 다시 버전을 구할 것입니다. [코드는 서식을 사용하기 위해 상단으로 이동했습니다] – wizpig64

1

HTML :

<form action="" method="post"> 
    {% csrf_token %} 
    <input type="hidden" name="width" value=""> 
    <input type="hidden" name="height" value=""> 
    <input type="hidden" name="image_data" value=""> 
</form> 

자바 스크립트 :

function submit_pixels(canvas) { 
    $('form input[name=image_data]').val(canvas.toDataURL("image/png")); 
    $('form input[name=width]').val(canvas.width); 
    $('form input[name=height]').val(canvas.height); 
    $('form').submit(); 
} 

장고 POST 요청보기 :

# in the module scope 
from io import BytesIO 
from PIL import Image 
import re 

# in your view function 
image_data = request.POST['image_data'] 
image_width = int(request.POST['width']) 
image_height = int(request.POST['height']) 
image_data = re.sub("^data:image/png;base64,", "", image_data) 
image_data = base64.b64decode(image_data) 
image_data = BytesIO(image_data) 
im = Image.open(image_data) 
assert (image_width, image_height,) == im.size 

범프 최대 설정의 최대 POST 크기 (예 : 20 ~ MB) :

# canvas data urls are large 
DATA_UPLOAD_MAX_MEMORY_SIZE = 20_000_000