jquery 使用Django捕获网络摄像头图像并上传数据库

mrfwxfqh  于 2023-08-04  发布在  jQuery
关注(0)|答案(1)|浏览(84)

我正在工作的形式,在那里我采取的用户详细信息,如姓名,电子邮件电话等。在相同的形式,一旦所有的数据提供,用户需要点击拍照按钮,相机得到启动,我能够捕捉图像和显示在img标签中的html。一旦这一切都完成了,用户需要点击保存按钮.所有这些数据(包括图像)都需要保存在后端创建的数据库/模型中。我已正确设置了媒体和静态文件的位置。我被困在保存图像。我尝试了很多方法,但没有帮助。我的模型保存数据-models.py

class UserDetails(models.Model):
    User_name = models.CharField(max_length= 300)
    User_phone = models.BigIntegerField()
    User_address = models.TextField()
    User_pic = models.FileField(upload_to='documents/%Y/%m/%d')

字符串
我的HTML表单

{% extends 'base.html' %}


{% load static %} {% block content %}

<div class="container-fluid">
    <div class="row">
     <div class="col-md-8">  
        <div id="accordion" role="tablist">

            <form method="POST" action="/usersave/" enctype="multipart/form-data">
                {% csrf_token %}
                  ....

               <div class="card-body">
                 <div class="row">
                   <div class="col-md-4 ml-auto mr-auto">
                      <div class="form-group">                                
                         <video id="video" autoplay ></video>                               
                         <canvas id="canvas"></canvas>                                
                   </div>
             <button id="startbutton1" class="btn btn-outline-secondary btn-sm">Take Photo</button>
                          <script src="{% static "assets/js/capture.js" %}"></script> 
                        </div>

                        .....
                    <div class="img  pull-center" >                                            
                    <img id ="photo" name="photo" alt="The screen capture will appear in this box.">                   
          </form>
      </div>                
    </div>  
 </div>


Views.py

def usersave(request):
if request.method== 'POST':        
    User_name = request.POST["Username"]
    User_phone = request.POST["Userphone"]
    User_address = request.POST["Useraddress"]
    pic = request.FILES["photo"]
    User_info= UserDetails(User_name=User_name, User_phone=User_phone, User_address=User_address, User_pic= pic)
    User_info.save()    
    return render(request, 'some.html')


使用这个capture.js文件,我可以拍摄照片并在img标签中填充HTML文件

(function() {

var width = 320;    
var height = 0;    
var streaming = false;  
var video = null;
var canvas = null;
var photo = null;
var startbutton1 = null;

function startup() {
  video = document.getElementById('video');
  canvas = document.getElementById('canvas');
  photo = document.getElementById('photo');
  startbutton1 = document.getElementById('startbutton1');

  navigator.mediaDevices.getUserMedia({video: true, audio: false})
  .then(function(stream) {
    video.srcObject = stream;
    video.play();
  })
  .catch(function(err) {
    console.log("An error occurred: " + err);
  });

  video.addEventListener('canplay', function(ev){
    if (!streaming) {
      height = video.videoHeight / (video.videoWidth/width);

      if (isNaN(height)) {
        height = width / (4/3);
      }

      video.setAttribute('width', width);
      video.setAttribute('height', height);
      canvas.setAttribute('width', width);
      canvas.setAttribute('height', height);
      streaming = true;
    }
  }, false);

  startbutton1.addEventListener('click', function(ev){
    takepicture();
    ev.preventDefault();
  }, false);

  clearphoto();
}

function clearphoto() {
  var context = canvas.getContext('2d');
  context.fillStyle = "#AAA";
  context.fillRect(0, 0, canvas.width, canvas.height);

  var data = canvas.toDataURL('image/png');
  photo.setAttribute('src', data);
}

function takepicture() {
  var context = canvas.getContext('2d');
  if (width && height) {
    canvas.width = width;
    canvas.height = height;
    context.drawImage(video, 0, 0, width, height);

    var data = canvas.toDataURL('image/png');
    photo.setAttribute('src', data);
  } else {
    clearphoto();
  }
}
window.addEventListener('load', startup, false);


})();
Take Photo button allows to capture the photo and put it in img tag
请指引我。谢啦,谢啦

rbpvctlc

rbpvctlc1#

我想这个答案会有帮助。

  • 让我们从后端实现开始回答:* 在您的models.py中,我更喜欢使用Image字段而不是file字段。
class Image(models.Model):
    username = models.CharField(max_length=30)
    image = models.ImageField(upload_to='images')

字符串
首先,请仔细配置您的媒体目录。

您的urls.py模块应如下所示。

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.image_upload, name='image_upload'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

您应该在settings.py中定义MEDIA_ROOT和MEDIA_URL。

BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATE_DIR = os.path.join(BASE_DIR, 'templates')

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

您的views.py应该如下所示,假设使用POST请求上载了映像。

# Import these methods
from django.core.files import File
from django.core.files.base import ContentFile
from django.core.files.temp import NamedTemporaryFile

def image_upload(request):
    context = dict()
    if request.method == 'POST':
        username = request.POST["username"]
        image_path = request.POST["src"]  # src is the name of input attribute in your html file, this src value is set in javascript code
        image = NamedTemporaryFile()
        image.write(urlopen(path).read())
        image.flush()
        image = File(image)
        name = str(image.name).split('\\')[-1]
        name += '.jpg'  # store image in jpeg format
        image.name = name
        if image is not None:
            obj = Image.objects.create(username=username, image=image)  # create a object of Image type defined in your model
            obj.save()
            context["path"] = obj.image.url  #url to image stored in my server/local device
            context["username"] = obj.username
        else :
            return redirect('/')
        return redirect('any_url')
    return render(request, 'index.html', context=context)  # context is like respose data we are sending back to user, that will be rendered with specified 'html file'.


要检查如何将网络摄像头图像数据发送到服务器,请参阅此问题的答案。如何从网络摄像头捕捉图片并将其存储在Django的ImageField或FileField中?
当从网络摄像头捕获图像时,输入字段的源(src)包含URL数据。而在服务器端,request.POST[“src”]实际上提供了URL数据,即临时空间中该图像的路径。

  • 现在,是时候讨论前端实现了:* 要实现网络摄像头接口,请参考这篇优秀的here教程。

我们使用WebRTC API来实现它。尽管有很多种方法,我还是喜欢使用WebRTC API。

因此,您的HTML代码看起来大致如下:

<!doctype html>
<html>
    {% block content %}
    {% load static %}
    <head>
        <title>VisionApp</title>
        <meta charset='utf-8'>
        <link rel="stylesheet" href="{% static 'css/style.css' %}" type="text/css" media="all">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <script type="module" src="{% static 'js/index.js' %}"></script>
    </head>
    <body>
        <div class="contentarea">
            <div class="Input">
                <form method="POST" name="inputForm" enctype='multipart/form-data'>
                    {% csrf_token %}
                    <div id="camera" class="camera">
                        <video id="video">Video stream not available.</video>
                        <button id="startbutton" type="button">Take photo</button>
                        <input id="webimg" value="" name="src" type="text" style="display: none;">
                        <canvas id="canvas">
                        </canvas>
                    </div>
                    <br>
                    <div>
                        <img id="photo" alt="your image">
                    </div>
                    <br>
                    <button type="submit" class="button" id="submit">Submit</button>
                </form>
            </div>
           <img src="{{ path }}" alt="The screen capture will appear in this box.">
        </div>
    </body>
    {% endblock %}
</html>


此处src =“{{ path }}",路径值来自上下文。在JavaScript中设置id=“photo”的img属性的值。

以下是CSS代码:

#video {
  border: 1px solid black;
  box-shadow: 2px 2px 3px black;
  width:320px;
  height:240px;
}

#photo {
  border: 1px solid black;
  box-shadow: 2px 2px 3px black;
  width:320px;
  height:240px;
}

#canvas {
  display:none;
}

.camera {
  width: 340px;
  display:inline-block;
}

.output {
  width: 340px;
  display:inline-block;
}

#startbutton {
  display:block;
  position:relative;
  margin-left:auto;
  margin-right:auto;
  bottom:32px;
  background-color: rgba(0, 150, 0, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.7);
  box-shadow: 0px 0px 1px 2px rgba(0, 0, 0, 0.2);
  font-size: 14px;
  font-family: "Lucida Grande", "Arial", sans-serif;
  color: rgba(255, 255, 255, 1.0);
}

.contentarea {
  font-size: 16px;
  font-family: "Lucida Grande", "Arial", sans-serif;
  width: 760px;
}

最后,您的JavaScript文件可能如下所示:

(function() {
  // The width and height of the captured photo. We will set the
  // width to the value defined here, but the height will be
  // calculated based on the aspect ratio of the input stream.

  var width = 320;    // We will scale the photo width to this
  var height = 0;     // This will be computed based on the input stream

  // |streaming| indicates whether or not we're currently streaming
  // video from the camera. Obviously, we start at false.

  var streaming = false;

  // The various HTML elements we need to configure or control. These
  // will be set by the startup() function.

  var video = null;
  var canvas = null;
  var photo = null;
  var startbutton = null;

  function startup() {
    video = document.getElementById('video');
    canvas = document.getElementById('canvas');
    photo = document.getElementById('photo');
    startbutton = document.getElementById('startbutton');

    navigator.mediaDevices.getUserMedia({video: true, audio: false})
    .then(function(stream) {
      video.srcObject = stream;
      video.play();
    })
    .catch(function(err) {
      console.log("An error occurred: " + err);
    });

    video.addEventListener('canplay', function(ev){
      if (!streaming) {
        height = video.videoHeight / (video.videoWidth/width);
      
        // Firefox currently has a bug where the height can't be read from
        // the video, so we will make assumptions if this happens.
      
        if (isNaN(height)) {
          height = width / (4/3);
        }
      
        video.setAttribute('width', width);
        video.setAttribute('height', height);
        canvas.setAttribute('width', width);
        canvas.setAttribute('height', height);
        streaming = true;
      }
    }, false);

    startbutton.addEventListener('click', function(ev){
      takepicture();
      ev.preventDefault();
    }, false);
    
    clearphoto();
  }

  // Fill the photo with an indication that none has been
  // captured.

  function clearphoto() {
    var context = canvas.getContext('2d');
    context.fillStyle = "#AAA";
    context.fillRect(0, 0, canvas.width, canvas.height);

    var data = canvas.toDataURL('image/png');
    photo.setAttribute('src', data);
  }
  
  // Capture a photo by fetching the current contents of the video
  // and drawing it into a canvas, then converting that to a PNG
  // format data URL. By drawing it on an offscreen canvas and then
  // drawing that to the screen, we can change its size and/or apply
  // other changes before drawing it.

  function takepicture() {
    var context = canvas.getContext('2d');
    if (width && height) {
      canvas.width = width;
      canvas.height = height;
      context.drawImage(video, 0, 0, width, height);
    
      var data = canvas.toDataURL('image/png');
      photo.setAttribute('src', data);
    } else {
      clearphoto();
    }
  }

  // Set up our event listener to run the startup process
  // once loading is complete.
  window.addEventListener('load', startup, false);
})();


希望这些代码片段能对您有所帮助!感谢您!

相关问题