2011-10-14 43 views
9

Tôi đang cố gắng lấy nội dung của canvas html5 và chuyển nó tới máy chủ django của tôi, sau đó nó sẽ được thao tác bằng PIL và được lưu dưới định dạng PNG. Dưới đây là những gì tôi có cho đến thời điểm này:Tải canvas html5 vào hình ảnh PIL với Django

Từ biểu mẫu HTML, người dùng nhấp vào nút "cập nhật", nội dung của canvas - với canvas.toDataURL() - được đưa vào hộp văn bản được gửi qua biểu mẫu POST . Cuối cùng điều này sẽ được tự động, nhưng không phải bây giờ.

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

Các canvasData là theo hình thức 'data: image/png; base64, iVBORw0KGgoAAAA ... vv ... =' khi nó được gửi qua. Sau đó, tôi đối phó với nó trong django:

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

Và đây là nơi tôi bị kẹt. Tôi không thể tìm ra cách để có được url dữ liệu được mã hóa base64 để tải hình ảnh vào một dạng có thể sử dụng với PIL.

Cảm ơn!

chỉnh sửa: đây là mã cho comment phía dưới:

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

Trả lời

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() 

hoặc nếu bạn cần phải tải nó vào PIL:

import cStringIO 

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

im = Image.open(tempimg) 
+0

tôi nhận được một ngoại lệ đệm không đúng khi Tôi sử dụng .decode(). Tôi có nên loại bỏ một số 'dữ liệu: hình ảnh ...' ở đầu chuỗi không? Tôi đã thử các biến thể khác nhau về điều đó và nó đã không giúp đỡ. – wizpig64

+0

Tôi đã cập nhật câu trả lời của mình bằng một regex đơn giản để lấy dữ liệu được mã hóa base64 từ URI dữ liệu. – Acorn

+0

Tôi đã tìm ra điều gì đã xảy ra với giải pháp của mình ngay bây giờ; python là tước một nhân vật phụ hơn tôi dự định. Cảm ơn rất nhiều vì sự giúp đỡ của bạn, tôi sẽ sử dụng phiên bản cũ của bạn vì tôi sẽ bị đau đầu hơn nhiều so với phiên bản này: [Mã được chuyển lên đầu để định dạng] – 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> 

Javascript:

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

Django POST Request Xem:

# 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 

Bump lên kích thước tối đa POST trong cài đặt của bạn (ví dụ: ~ 20 MB):

# canvas data urls are large 
DATA_UPLOAD_MAX_MEMORY_SIZE = 20_000_000 
Các vấn đề liên quan