在django——canvas元素中上传并保存用户摄像头截图到文件

upload and save screenshot taken from users webcam in django --canvas element to file

本文关键字:摄像头 用户 文件 保存 canvas django 元素      更新时间:2023-09-26

我正在做一个关于web开发的项目,我必须使用我的网络摄像头上传用户的输入图像。我使用的是Python Django 1.6.5框架。

我能够访问用户的网络摄像头,并能够拍摄快照并在HTML页面上查看它。(它在HTML页面中以画布的形式显示。)这是在我的HTML页面中从网络摄像头捕获图像的代码。

为了更好的理解,我在HTML页面中给出了注释。

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href ="/static/css/styles.css" type="text/css"/>
<title>Capture image </title>
</head>
<body>
<form id="webcamPageForm" method="POST" enctype="multipart/form-data" action="/tryonViewWC/{{frame.slug}}/">
{% csrf_token %}
<video id="vid" width="640" height="480" autoplay></video><!-- shows my video stream playing -->
<input type="file" id="imagewc" name="imagewc" onclick="snapshot();" accept="image/*" capture> <!-- opens my hard drive and expects input from hard drive-->
<canvas id="canvas" name="canvas" width="640" height="480" style="border:1px solid #d3d3d3;"></canvas><br> <!--captured image displayed here-->
<input type="submit" id="SubmitWebCam" name="SubmitWebCam"  class="myButton" value= "Done" style="display:none"><br><!-- on submit should send user-captured snapshot to views.py-->
<script type="text/javascript">
    var video = document.querySelector("#vid");
    var canvas = document.querySelector('#canvas');
    var ctx = canvas.getContext('2d');
    var localMediaStream = null;
    var onCameraFail = function (e) {
        console.log('Camera did not work.', e);
        };
    function snapshot() {  
        if (localMediaStream) {
            ctx.drawImage(video, 0, 0);   // This draws the captured image on the canvas
        }
         document.getElementById('SubmitWebCam').style.display="block";
    }
    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
    window.URL = window.URL || window.webkitURL;
    navigator.getUserMedia({video:true}, function (stream) {
        video.src = window.URL.createObjectURL(stream);
        video.play();
        localMediaStream = stream;
    }, onCameraFail);
</script>
</form>
</body>
</html>

我在文件输入中使用了capture attribute,因为我在这里阅读

http://www.html5rocks.com/en/tutorials/getusermedia/intro/#toc-screenshot和http://dev.w3.org/2009/dap/camera/#dfn-capture

,并期望在画布中捕获的屏幕截图将被作为文件输入。

考虑到这一点,我创建了forms.pyviews.py

这是我的forms.py

from django import forms
class ImageUploadWCForm(forms.Form):
    print("Image upload from WC form.")        
    imagewc = forms.ImageField(label='Select a file')              
    print "Hi in Webcam ", imagewc

和我的views .py

def upload_webcam(request, frameslug):   
  print "in upload WBCAM "     
  if request.method == 'POST':
      form = ImageUploadWCForm(request.POST, request.FILES)
      #print "FILES", request.FILES
      if form.is_multipart():
          uploadFile=save_filewc(request.FILES['imagewc'])
          print('vALID iMAGE')
      else:
          print('Invalid image')
  else:
      form = ImageUploadWCForm()   
  return render_to_response('dummy.html')

def save_filewc(file, path=''):
  filename = "uploadedPicWC.jpg"
  fd = open('%s/%s' % (MEDIA_ROOT1, str(path) + str(filename)), 'wb')
  print "fd", fd
  print "str(path)",str(path)
  print "str(filename)",str(filename)
  for chunk in file.chunks():
      fd.write(chunk)
  fd.close()

理想情况下,视图中的这个函数应该获取用户捕获的图像,并将其保存到指定的位置。

但是我观察到的是uploadFile=save_filewc(request.FILES['imagewc'])行给出了一个错误。

 Exception Type:    MultiValueDictKeyError
    Exception Value:    "'imagewc'"

这显然意味着来自画布的数据不会进入输入类型文件。

我所理解的是Django视图需要输入类型"file"从表单作为用户输入上传到服务器的表单提交。(我对此有更清晰的理解,因为我有一个类似的问题,以前我能够解决它。)

HttpRequest.FILES
A dictionary-like object containing all uploaded files. Each key in FILES is the name from the <input type="file" name="" />. Each value in FILES is an UploadedFile.

已在https://docs.djangoproject.com/en/dev/ref/request-response/django.http.HttpRequest.FILES

那么,我可以从HTML转换画布数据(保存我捕获的屏幕截图)并通过将其存储在HTML文件输入中的views.py中接收它的方式是什么?请帮助。现在困住一段时间了。提前感谢:)

"并期望在画布中捕获的屏幕截图将被作为文件输入。"不幸的是,你做了一个假设,这不是基于任何证据:目前你的代码没有连接到如何使<canvas>内容作为<form>提交。

使数据从画布到服务器的一种方法(因为有替代方法)

  • 导出<canvas>内容为图像(使用toDataUrl())

  • 使用AJAX请求向服务器提交base64编码的数据

这已经解决了之前的问题如何将HTML5画布保存为服务器上的图像-在这种情况下,你需要解码服务器端的base64 URL:

https://stackoverflow.com/a/15376482/315168