Javascript 如何通过输入字段发送捕获的网络摄像头图像并保存到服务器

Javascript 如何通过输入字段发送捕获的网络摄像头图像并保存到服务器,javascript,django,image,server,webcam,Javascript,Django,Image,Server,Webcam,我在做一个项目,用户可以通过使用网络摄像头更改个人资料图片。 我已通过网络摄像头成功捕获图像,但无法将该捕获图像附加到我的 形式 这是我的HTML代码 <div class="form-group"> <label for="exampleInputFile">Profile Picture</label> <div class="input-group"> <div class="custom-file">

我在做一个项目,用户可以通过使用网络摄像头更改个人资料图片。 我已通过网络摄像头成功捕获图像,但无法将该捕获图像附加到我的 形式

这是我的HTML代码

<div class="form-group">
<label for="exampleInputFile">Profile Picture</label>
    <div class="input-group">
        <div class="custom-file">
            <input type="file" id="photo" class="custom-file-input" name = "profile_pic" accept="image/png,image/jpg,image/jpeg">
            <label class="custom-file-label" for="exampleInputFile">Choose Image</label>
        </div>
    </div>
</div>


<div class="camera">
    <video id="video">Video stream not available.</video>
    <button type="button" id="startbutton" class="btn btn-success" data-toggle="modal" data- 
    target="#modal-success">Take photo</button>
</div>

侧面图
选择图像
视频流不可用。
拍照
这是我的js代码,我遵循它寻求帮助

<script>
  (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 = 770;    // We will scale the photo width to this
      var height = 900;   // 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', 340);
            video.setAttribute('height', 300);
            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/ ');
          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);
    })(); 



</script>

(功能(){
//拍摄照片的宽度和高度。我们将设置
//宽度设置为此处定义的值,但高度将为
//基于输入流的纵横比计算。
var width=770;//我们将按此比例缩放照片宽度
var height=900;//这将基于输入流进行计算
//|流媒体|表示我们当前是否正在流媒体
//摄像机的视频。显然,我们从错误开始。
var=false;
//我们需要配置或控制的各种HTML元素
//将由startup()函数设置。
var-video=null;
var=null;
var=null;
var startbutton=null;
函数启动(){
video=document.getElementById('video');
canvas=document.getElementById('canvas');
photo=document.getElementById('photo');
startbutton=document.getElementById('startbutton');
navigator.mediaDevices.getUserMedia({video:true,audio:false})
.then(函数(流){
video.srcObject=流;
video.play();
})
.catch(函数(err){
log(“发生错误:+err”);
});
video.addEventListener('canplay',函数(ev){
如果(!流){
高度=video.videoHeight/(video.videoWidth/宽度);
//Firefox目前有一个无法读取高度的错误
//如果发生这种情况,我们将进行假设。
如果(isNaN(高度)){
高度=宽度/(4/3);
}
video.setAttribute('width',340);
video.setAttribute('height',300);
canvas.setAttribute('width',width);
canvas.setAttribute('height',height);
流=真;
}
},假);
startbutton.addEventListener('click',函数(ev){
拍摄照片();
ev.preventDefault();
},假);
clearphoto();
}
//在照片中填入一个没有被删除的标记
//被俘。
函数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',数据);
}
//通过获取视频的当前内容来捕获照片
//并将其绘制成画布,然后将其转换为PNG
//格式化数据URL。在屏幕外的画布上绘制数据URL,然后
//将其绘制到屏幕上,我们可以更改其大小和/或应用
//绘制前的其他更改。
函数takepicture(){
var context=canvas.getContext('2d');
if(宽度和高度){
画布宽度=宽度;
canvas.height=高度;
drawImage(视频,0,0,宽度,高度);
var data=canvas.toDataURL('image/');
photo.setAttribute('src',数据);
}否则{
clearphoto();
}
}
//设置事件侦听器以运行启动进程
//一旦装载完成。
window.addEventListener('load',startup,false);
})(); 
现在,我如何将捕获的图像放入
字段,以便上传到服务器


注意:我不想为此使用ajax。

1-将base64图像作为字符串发送,然后在服务器端将其转换为文件

2-将Base64字符串转换为Blob,以将其作为文件上载到服务器

我解释第二种选择:

首先,使用此函数将Base64字符串转换为Blob:

function b64toBlob(b64Data, contentType, sliceSize) {
    contentType = contentType || '';
    sliceSize = sliceSize || 512;

    var byteCharacters = atob(b64Data); // window.atob(b64Data)
    var byteArrays = [];

    for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        var slice = byteCharacters.slice(offset, offset + sliceSize);

        var byteNumbers = new Array(slice.length);
        for (var i = 0; i < slice.length; i++) {
            byteNumbers[i] = slice.charCodeAt(i);
        }

        var byteArray = new Uint8Array(byteNumbers);

        byteArrays.push(byteArray);
    }

    var blob = new Blob(byteArrays, {type: contentType});
    return blob;
}
最后,您可以使用任何方法发送formData,例如:

var request = new XMLHttpRequest();
request.open("POST", "SERVER-URL");
request.send(formDataToUpload);
我希望这能帮助你;)


查看此链接获取完整的源代码:

谢谢您的回答,但我不想用javascript发送我的图像。难道不能用过程表单提交方式发送图像文件吗?无论如何,您必须使用Javascript。您可以定义一个表单,当用户单击“提交”按钮时,阻止默认操作并使用javascript发送表单。@Antu如果您能详细解释为什么要使用“表单提交”程序发送表单,我们可能会得到新结果。实际上,我的项目只是一名医生,他将为患者注册他的面部图像和医疗细节。如果我使用ajax,我就不能发送带有数据的图像,因为我不使用ajax进行数据发送。我需要先保存数据,然后我需要把病人的面部图像。(主键外键问题)谢谢,我解决了这个问题,我会更新答案。
var form = document.getElementById("myAwesomeForm");

var ImageURL = photo; // 'photo' is your base64 image
// Split the base64 string in data and contentType
var block = ImageURL.split(";");
// Get the content type of the image
var contentType = block[0].split(":")[1];// In this case "image/gif"
// get the real base64 content of the file
var realData = block[1].split(",")[1];

// Convert it to a blob to upload
var blob = b64toBlob(realData, contentType);

// Create a FormData and append the file with "image" as parameter name
var formDataToUpload = new FormData(form);
formDataToUpload.append("image", blob);
var request = new XMLHttpRequest();
request.open("POST", "SERVER-URL");
request.send(formDataToUpload);
            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/jpeg');
                var request = new XMLHttpRequest();
                request.open("POST", 'SERVER_URL');
                request.send(data);
              } else {
                clearphoto();
              }
            }