0

I am trying to capture a photo from a webcam and store it in a FileField or ImageField. But I am not getting how to get the captured image data on request. Please check my HTML template, javascript code, and views.py. Can anyone suggest a way to get this image data captured using javascript, on submitting the form in HTML?

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

My HTML form

{% extends 'base.html' %}
{% load static %}
{% block content %}  
 
<!DOCTYPE html>
<html lang="en">

<body class="">
 
      <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>
  </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')

Using this capture.js file I am able to take photo and populate the HTML file in img tag

(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);
  })();
James Z
  • 12,209
  • 10
  • 24
  • 44
Namballa Mukesh
  • 174
  • 3
  • 15

2 Answers2

1

I know it is difficult to communicate between Javascript and Django, we should use Ajax or jQuery requests for that. But for this problem, I found a way to get the image data from the webcam to the backend(Django).

When the user captures a photo, the photo is stored in the local temp folder. We can set the src attribute of the image element in HTML with the captured image URL data, which is the URL of the image in the temp folder.

Now, when the user clicks on submit button, the src of the image will come in the post request. As src has the URL path of a captured image in the temp folder, we can read it and store it in our model. Below code is the sample.

In my views.py, I can add

path = request.POST["src"]
image = NamedTemporaryFile()
image.write(urlopen(path).read())
image.flush()
image = File(image)
name = str(image.name).split('\\')[-1]
name += '.jpg'
image.name = name
obj = Image.objects.create(image=image)
obj.save()

Rest of the code is the same as posted in the question, including the Javascript and HTML code.

Namballa Mukesh
  • 174
  • 3
  • 15
0

In your form the img is just in a <img> tag it needs to be in an input

See this answer for how to turn DataUrl to form input

<input type="hidden" name="photo" id="photo" />

your photo should be in an input like above.

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');
         
        // Set the form value to data here

        photo.setAttribute('src', data);
      } else {
        clearphoto();
      }
    }
Reed Jones
  • 1,367
  • 15
  • 26