Load an html5 canvas into a PIL Image with Django

前端 未结 4 1569
孤独总比滥情好
孤独总比滥情好 2020-12-15 09:54

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

相关标签:
4条回答
  • 2020-12-15 10:06

    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()
    
    0 讨论(0)
  • 2020-12-15 10:13

    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)
    
    0 讨论(0)
  • 2020-12-15 10:14

    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
    
    0 讨论(0)
  • 2020-12-15 10:27
    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)
    
    0 讨论(0)
提交回复
热议问题