I'm trying to get the contents of an html5 canvas and pass it to my django server, where it will then be manipulated with PIL and saved as a PNG. Here's what I have so far:
From the HTML form, the user clicks the "update" button, the canvas's contents - with canvas.toDataURL() - gets dumped into a text box that is submitted via a POST form. Eventually this will be automatic, but not for now.
<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>
The canvasData is in the form of 'data:image/png;base64,iVBORw0KGgoAAAA...etc...=' when it gets sent over. Then I deal with it in django:
from PIL import Image
...
canvasData = request.POST.get('canvasData', '')
im = Image.somehowLoad(canvasData)
...
im.save('canvas.png')
And this is where i'm stuck. I can't figure out how to get the base64-encoded data url to load up the image into a usable form with PIL.
Thanks!
edit: here's the code for the bottom comment:
>>> d
'data:image/png;base64,iVBORw0K'
>>> d.strip('data:image/png;base64,')
'VBORw0K'
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()
or if you need to load it into PIL :
import cStringIO
tempimg = cStringIO.StringIO(imgstr.decode('base64'))
im = Image.open(tempimg)
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 View:
# in the module scope
from io import BytesIO
from PIL import Image
import re
import base64
# 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 up the maximum POST size in your settings (example: ~20 MB):
# canvas data urls are large
DATA_UPLOAD_MAX_MEMORY_SIZE = 20_000_000
In 2019 with python3 i tried Acorn answer, and i got Error 'str' object has no attribute 'decode ' So i did some searching and adjusted the code and it worked here it is
from binascii import a2b_base64
import re
datauri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
imgstr = re.search(r'base64,(.*)', datauri).group(1)
binary_data = a2b_base64(imgstr)
Out = open('image.png', 'wb')
Out.write(binary_data)
Out.close()
For Django 3.0 and python 3.7 code in the html file (which are called templates in the django)
<form method="POST" id="form1"> {% csrf_token %} <canvas id="camera--sensor"></canvas> <!-- Camera view --> <video id="camera--view" autoplay playsinline></video> <!-- Camera output --> <img src="//:0" alt="" id="camera--output" onclick="show()"> <!-- Camera trigger --> <input type="hidden" id="captured_image" name="captured_image"> <input id="upload_image" type="submit" onclick="save()" value="Upload the image"> </form>
in the javascript file
var canvas; function save(){ canvas = document.getElementById('camera--sensor'); document.getElementById('captured_image').value = canvas.toDataURL('image/png'); }
in the views.py file for Django
def capture_image(request):
if request.method=="POST":
# print("-------",request.POST)
if request.POST.get('captured_image'):
captured_image = request.POST.get('captured_image')
# imgstr = captured_image.decode('base64')
imgstr = re.search('base64,(.*)', captured_image).group(1)
imgstr = base64.b64decode(imgstr)
# print(imgstr)
tempimg = io.BytesIO(imgstr)
im = Image.open(tempimg)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.