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



我正在处理一个表单,其中我正在获取用户详细信息,如姓名,电子邮件电话等。在提供所有数据后,以相同的形式,用户需要单击拍照按钮,相机启动,我能够捕获图像并在 html 中的 img 标签中显示。 完成所有这些操作后,用户需要单击保存按钮。所有这些数据(包括图像(都需要保存在后端创建的数据库/模型中。我已正确设置媒体和静态文件位置。 我被困在保存图像上。我尝试了很多选择,但没有帮助。 我的模型保存数据 - 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')

我的网页表单

{% extends 'base.html' %}

{% 负载静态 %} {% 块内容 %}

<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')

使用此捕获.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);

}(((;

拍照按钮允许捕获照片并将其放入img标签中

请指导我。 谢谢

我认为这个答案会有所帮助。

让我们从后端实现开始回答: 在您的 models.py 中,我更喜欢使用图像字段而不是文件字段。

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 数据。在服务器端,请求。POST["src"] 实际上为我们提供了 URL 数据,这是临时空间中该图像的路径。

现在,是时候讨论前端实现了:要实现网络摄像头接口,请参阅此处的优秀教程。

我们使用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 }}",路径值来自上下文。id="photo"的img属性的值是在javascript中设置的。

这是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);
})();

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

最新更新