Tuesday, November 3, 2015

HTML5 Image Capture on Mobile and Server-side Handling

Since on mobile browsers, the video tag is not fully supported, one need to use the following to take a shot.

<button onclick="$('#inputv').trigger('click');">Take a shot</button>
<input type="file" id="inputv" name="inputv" accept="image/*" capture="camera" style="display:none">
<div id="f_img"></div>

And on js side, you need to utilize FileReader object to read the image shot from it. The image is stored in base64 string format, which can be added to src attribute to show the image on the page.

window.addEventListener("DOMContentLoaded", function(){
    if (window.File && window.FileReader && window.FileList && window.Blob) {
        $("#inputv").change(function(e){
                var f = e.target.files[0];
                //  alert(f.size);
                var reader = new FileReader();
                reader.onload = function(e) {
                    //write your code to process the image
                    $("#f_img").html('<img src="' + e.target.result + '">');
                };
                reader.readAsDataURL(f);
        });
    // Great success! All the File APIs are supported.
    } else {
        $("#notice").append('The File APIs are not fully supported in this browser.');
    }

The image in base64 can be uploaded to the server part using input tag with the type as text. A possible server-side handling witten in python can be the following:

from flask import request

image = request.form['image']

def save_b64(image):
    img_str = str(image) #unicode to str obj
    head="data:image/jpeg;base64,"
    if str(img_str).startswith(head):
        l = len(head)
        img_str = img_str[l:]
    
    import time
    timestr = time.strftime("%Y%m%d%H%M%S")
    path = "image/capture-" + timestr + ".jpg"
    try:
        img = open(path, "wb")
        img.write(img_str.decode('base64'))
        img.close()
        return path
    except Exception as e:
        return False