2011-10-14 11 views
9

Estoy tratando de obtener el contenido de un lienzo html5 y pasarlo a mi servidor django, donde se manipulará con PIL y se guardará como PNG. Esto es lo que tengo hasta ahora:Cargue un lienzo html5 en una imagen PIL con Django

Desde el formulario HTML, el usuario hace clic en el botón "actualizar", los contenidos del lienzo - con canvas.toDataURL() - se vuelca en un cuadro de texto enviado a través de un formulario POST . Eventualmente esto será automático, pero no por ahora.

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

El canvasData es en forma de 'datos: image/png; base64, iVBORw0KGgoAAAA ... etc ... =' cuando se envía a través de. Entonces lo trato en django:

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

Y aquí es donde estoy atascado. No puedo entender cómo obtener la URL de datos codificada en base64 para cargar la imagen en una forma utilizable con PIL.

Gracias!

edición: aquí está el código para el comentario final:

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

Respuesta

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

o si necesita cargarlo en PIL:

import cStringIO 

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

im = Image.open(tempimg) 
+0

Estoy recibiendo una excepción cuando el relleno incorrecta Yo uso .decode(). ¿Debo eliminar algunos de los 'datos: imagen ...' al comienzo de la cadena? He intentado diferentes variaciones sobre eso y no ha ayudado. – wizpig64

+0

He actualizado mi respuesta con una expresión regular simple para obtener los datos codificados en base64 del URI de datos. – Acorn

+0

Descubrí lo que estaba mal con mi solución en este momento; Python está eliminando un personaje extra de lo que pretendía. (¿Alguna idea de por qué es esto?) Muchas gracias por su ayuda, voy a ir con su versión de re ya que voy a tener dolores de cabeza mucho menos que con este: [Código movido a la publicación superior para formatear] – 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 Petición POST Vista:

# 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 

LEVANTACOLA el tamaño máximo de POST en la configuración (ejemplo: ~ 20 MB):

# canvas data urls are large 
DATA_UPLOAD_MAX_MEMORY_SIZE = 20_000_000 
Cuestiones relacionadas