使用 Django 将 html5 canvas 加载到 PIL 图像中

发布于 2024-12-10 11:01:17 字数 1037 浏览 0 评论 0原文

我试图获取 html5 画布的内容并将其传递到我的 django 服务器,然后使用 PIL 对其进行操作并保存为 PNG。这是我到目前为止所得到的:

从 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 的格式为“data:image/png;base64,iVBORw0KGgoAAAA...etc...=”。然后我在 django 中处理它:

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'

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'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

往事风中埋 2024-12-17 11:01:17
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)
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)
被你宠の有点坏 2024-12-17 11:01:17

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 请求视图:

# 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

增加设置中的最大 POST 大小(例如:~20 MB):

# canvas data urls are large
DATA_UPLOAD_MAX_MEMORY_SIZE = 20_000_000

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
凌乱心跳 2024-12-17 11:01:17

在 2019 年,我用 python3 尝试了 Acorn 答案,然后得到了
错误“str”对象没有属性“解码”
所以我做了一些搜索并调整了代码,它在这里工作了

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

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()
猛虎独行 2024-12-17 11:01:17

适用于 Django 3.0 和 python 3.7
html文件中的代码(在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>

在 JavaScript 文件中

var canvas;
function save(){
            canvas = document.getElementById('camera--sensor');
            document.getElementById('captured_image').value = canvas.toDataURL('image/png');
          
        }

在 Django 的views.py 文件中

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)

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文