我如何从客户端(html)拍照并将其保存到服务器端(Python)

Posted

技术标签:

【中文标题】我如何从客户端(html)拍照并将其保存到服务器端(Python)【英文标题】:How do i take picture from client side(html) and save it to server side(Python) 【发布时间】:2018-04-02 07:36:09 【问题描述】:

我是 python 新手,我使用 python 做了一个应用程序,我想使用 html 和 AJAX javascript 从我的网络摄像头捕获图像并将其保存到服务器端 python。我已经完成了使用客户端 HTML 捕获图像,但我不知道如何保存数据并将其从 html 客户端传递到服务器端 python。如果有人这样做,请你帮我... 先感谢您... 我的.html:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Get User Media - Photo</title>
</head>
<body>
<button id="take">Take a photo</button><br />
<video id="v"></video>
<canvas id="canvas" style="display:none;"></canvas>

<img src="D:/VoteTest/img.jpg" id="photo" >
<script>
    ;(function()
        function userMedia()
            return navigator.getUserMedia = navigator.getUserMedia ||
            navigator.webkitGetUserMedia ||
            navigator.mozGetUserMedia ||
            navigator.msGetUserMedia || null;

        


        // Now we can use it
        if( userMedia() )
            var videoPlaying = false;
            var constraints = 
                video: true,
                audio:false
            ;
            var video = document.getElementById('v');

            var media = navigator.getUserMedia(constraints, function(stream)

                // URL Object is different in WebKit
                var url = window.URL || window.webkitURL;

                // create the url and set the source of the video element
                video.src = url ? url.createObjectURL(stream) : stream;

                // Start the video
                video.play();
                videoPlaying  = true;
            , function(error)
                console.log("ERROR");
                console.log(error);
            );


            // Listen for user click on the "take a photo" button
            document.getElementById('take').addEventListener('click', function()
                if (videoPlaying)
                    var canvas = document.getElementById('canvas');
                    canvas.width = video.videoWidth;
                    canvas.height = video.videoHeight;
                    canvas.getContext('2d').drawImage(video, 0, 0);
                    var data = canvas.toDataURL('image/webp');
                    document.getElementById('photo').setAttribute('src', data);
                
            , false);



         else 
            console.log("KO");
        
    )();
</script>
</body>
</html>

【问题讨论】:

【参考方案1】:

我最近刚刚为一个项目做了这个。您可以使用 XHR 在表单数据中发送图像:

let formdata = new FormData();
formdata.append("image", data);
let xhr = new XMLHttpRequest();
xhr.open('POST', 'http://yourserver/image', true);
xhr.onload = function () 
    if (this.status === 200)
        console.log(this.response);
    else
        console.error(xhr);
;
xhr.send(formdata);

我在使用toDataURL 转换画布时遇到问题,因此我使用toBlob 进行更轻松的转换:

canvas.toBlob(callBackToMyPostFunctionAbove, 'image/jpeg');

这是一个带有嵌入式 JavaScript 和我的 Python 服务器的示例 HTML 文件。

HTML 和嵌入式 JavaScript

JavaScript 使用:

    getUserMedia 启动本地视频流 鼠标单击图像以启动图像捕获 一个画布对象,用于保存来自 getUserMedia 流的图像 XHR 将文件作为表单数据发送

代码:

<!DOCTYPE html>
<html>
<head>
    <title>Post an Image test</title>
    <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
</head>
<style>
    /* mirror the image */
    video, canvas 
    transform: scale(-1, 1); /*For Firefox (& IE) */
    -webkit-transform: scale(-1, 1); /*for Chrome & Opera (& Safari) */

</style>
<body>
<video id="myVideo" autoplay></video>

<script>

    let v = document.getElementById("myVideo");

    //create a canvas to grab an image for upload
    let imageCanvas = document.createElement('canvas');
    let imageCtx = imageCanvas.getContext("2d");

    //Add file blob to a form and post
    function postFile(file) 
        let formdata = new FormData();
        formdata.append("image", file);
        let xhr = new XMLHttpRequest();
        xhr.open('POST', 'http://localhost:5000/image', true);
        xhr.onload = function () 
            if (this.status === 200)
                console.log(this.response);
            else
                console.error(xhr);
        ;
        xhr.send(formdata);
    

    //Get the image from the canvas
    function sendImagefromCanvas() 

        //Make sure the canvas is set to the current video size
        imageCanvas.width = v.videoWidth;
        imageCanvas.height = v.videoHeight;

        imageCtx.drawImage(v, 0, 0, v.videoWidth, v.videoHeight);

        //Convert the canvas to blob and post the file
        imageCanvas.toBlob(postFile, 'image/jpeg');
    

    //Take a picture on click
    v.onclick = function() 
        console.log('click');
        sendImagefromCanvas();
    ;

    window.onload = function () 

        //Get camera video
        navigator.mediaDevices.getUserMedia(video: width: 1280, height: 720, audio: false)
            .then(stream => 
                v.srcObject = stream;
            )
            .catch(err => 
                console.log('navigator.getUserMedia error: ', err)
            );

    ;

</script>
</body>
</html>

这使用adapter.js在不同的浏览器上填充getUserMedia,没有任何错误检查。

Python 服务器

下面是一个使用 Flask 作为 Web 服务器的 Python 示例:

from flask import Flask, request, Response
import time

PATH_TO_TEST_IMAGES_DIR = './images'

app = Flask(__name__)

@app.route('/')
def index():
    return Response(open('./static/getImage.html').read(), mimetype="text/html")

# save the image as a picture
@app.route('/image', methods=['POST'])
def image():

    i = request.files['image']  # get the image
    f = ('%s.jpeg' % time.strftime("%Y%m%d-%H%M%S"))
    i.save('%s/%s' % (PATH_TO_TEST_IMAGES_DIR, f))

    return Response("%s saved" % f)

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

【讨论】:

【参考方案2】:

如果您在服务器端寻找 php,我就是这样做的。

使用 jquery 将图像数据发布到 php 脚本:

var imgData = canvas.toDataURL('image/png');
$.post("https://path-to-your-script/capture.php", image: imgData,
    function(data) 
        console.log('posted');
);

php 脚本如下:

capture.php

$data = $_POST['image'];

// remove "data:image/png;base64," from image data.
$data = str_replace("data:image/png;base64,", "", $data);

// save to file
file_put_contents("/tmp/image.png", base64_decode($data));

【讨论】:

以上是关于我如何从客户端(html)拍照并将其保存到服务器端(Python)的主要内容,如果未能解决你的问题,请参考以下文章

在 React(客户端)中上传 .json 文件并将其发送到 Node(服务器端)

如何从服务器端加密数据并将其传递到客户端(javascript)并解密和使用它

如何从客户端(android-java app)发送数据到解析服务器,处理它,将其保存在parse-dashboard中并将结果发送给客户端?

如何将数据从客户端(android-java 应用程序)发送到解析服务器,对其进行处理,将其保存在 parse-dashboard 中并将结果发送回客户端?

Android:如何用相机拍照并将位图转换为字节数组并保存到sqlite db?

如何从 Javascript 提示框中获取值并将其传递给 PHP 变量以便能够保存在 SQL 中?