首页 > 解决方案 > 如何使用 canvas html5 摆脱闪烁的图像并清除以前的画布结果?

问题描述

我正在使用 html5 使用 drawImage() 在黑色图像上绘制人体姿势关键点。当我第一次上传视频时,它会正确绘制。但是当我上传第二个视频时,前一个视频的结果会被保留,而当前视频的结果会导致图像在绘制时闪烁。在代码下方找到 -

$(document).ready(function () {
      let fileURL;
      let file_ext;
      let width, height; 
      var canvas = document.getElementById('canvas');
      var ctx = canvas.getContext('2d');
      var image_bg;//document.getElementById('source');
      let video;

      // The detected positions will be inside an array
      let poses = [];
      let poseNet;
      

      $("#selectVideoFile").filestyle({htmlIcon: '<span><i class="fa fa-search"></i></span>&nbsp;',
        size: "md",
        text: ' Select',
        btnClass : "btn btn-change",
        placeholder: "Upload person video"          
      });

      function isEmpty(obj) {
        for(var key in obj) {
            if(obj.hasOwnProperty(key))
                return false;
        }
        return true;
      }

      function showInpVideo(input) {
        if (!(isEmpty(fileURL))) {
          URL.revokeObjectURL(fileURL);  
        }
        var fileInput = document.getElementById('selectVideoFile');
        fileURL = window.URL.createObjectURL(fileInput.files[0]);

        $('#inputVideo').html("");
        $('#inputVideo').append('<video controls id="video" src="'+ fileURL +'" alt="Input Video" width="620" height="360"></video>');                
      };

      

      // Listen for the change event on our input element so we can 
        // get the video file selected by the user
      document.getElementById('selectVideoFile').addEventListener('change', function(e) {
                    
          var fileName = $(".vidFile").val().replace(/C:\\fakepath\\/i, '');
          file_ext = (fileName !== '') ? fileName.split(".")[1].toLowerCase() : '';
      
          console.log('Video File extension: ', file_ext);
          
          $('#inputVideo').html("");
          $('#canvasVideo').html("");
              
          console.log('On change video name: ', fileName);
          
          $('.input-video-loader').hide();
          // $('.processed-video-loader').hide();
          $('#inputVideo').hide();
          $('.caption-text-video-input').hide();
          $('.caption-text-video-processed').hide();
          $('#canvas').hide();
          $('#displayVideos').hide();
          $('#videoBtn').hide();
        
          // If file is selected or file selected has extension mp4

          if (($('#selectVideoFile').val() !== '') && (file_ext === 'mp4')) {
        
            $('#displayVideos').show();
            $('.caption-text-video-input').show();
            $('.input-video-loader').show();
            $('#inputVideo').show();
              
            // Show input video
            showInpVideo();
              
            $('.input-video-loader').hide();
            
            vidId  = document.getElementById('video');
            console.log('video: ', vidId);
            height = $('#video').height();
            width = $('#video').width();
            
            mdlSetup(vidId);

              
            console.log(width+' '+height);
            
            
        
        } else {
            $('#displayVideos').hide();
            alert("Please upload person video file having extension -- (.mp4)!")
            $('#selectVideoFile').val('');
          }
        });
        
        function mdlSetup(vidId){
            console.log('***  Model Setup  ****');
            video = vidId;      
            
            //Posenet
            poseNet = ml5.poseNet(video, modelReady);           
            console.log('Model Loaded ');
            poseNet.on('pose', gotPoses);
        }

      
      // A function to draw the video and poses into the canvas.
      // This function is independent of the result of posenet
      // This way the video will not seem slow if poseNet 
      // is not detecting a position
      function drawVideoIntoCanvas() {
        //ctx.clearRect(0, 0, 620, 360);
        // console.log('Draw Canvas: ', ctx);       

        // Draw the video element into the canvas
        ctx.drawImage(image_bg, 0, 0, 620, 360);
        // We can call both functions to draw all keypoints and the skeletons
        drawKeypoints();
        drawSkeleton();
        requestAnimationFrame(drawVideoIntoCanvas);
      }

      // A function that gets called every time there's an update from the model
      function gotPoses(results) {
        poses = results;
        //console.log('Poses : ', poses)
      
      }

      function modelReady() {
        // document.getElementById('status').innerHTML = 'Model Loaded'
        console.log("model ready")
        poseNet.multiPose(video);
      }

      // A function to draw ellipses over the detected keypoints
      function drawKeypoints()  {      
        // Loop through all the poses detected
        for (let i = 0; i < poses.length; i=i+2) {
        // For each pose detected, loop through all the keypoints
        for (let j = 0; j < poses[i].pose.keypoints.length; j++) {
          let keypoint = poses[i].pose.keypoints[j];
          // Only draw an ellipse is the pose probability is bigger than 0.2
          if (keypoint.score > 0.2) {
          ctx.strokeStyle = 'rgb(0, ' + Math.floor(255 - 42.5 * i) + ', ' + 
                      Math.floor(255 - 42.5 * j) + ')';
          //ctx.strokeStyle = '#003300';
          ctx.fillStyle = 'rgb(17, 240, 110)';
          ctx.beginPath();
          ctx.arc(keypoint.position.x, keypoint.position.y, 2, 0, 2 * Math.PI);
          ctx.stroke();
          }
         }
        } 
      }

      // A function to draw the skeletons
      function drawSkeleton() {
        // Loop through all the skeletons detected
        for (let i = 0; i < poses.length; i=i+2) {
          // For every skeleton, loop through all body connections
          for (let j = 0; j < poses[i].skeleton.length; j++) {
            let partA = poses[i].skeleton[j][0];
            let partB = poses[i].skeleton[j][1];
            ctx.beginPath();
            ctx.moveTo(partA.position.x, partA.position.y);
            ctx.lineTo(partB.position.x, partB.position.y);
          ctx.lineWidth = 2;
          
          // set line color
          ctx.strokeStyle = '#13f0c7'
            ctx.stroke();
          }
        }
      }

      // video button controls
    $('#play-btn').click(function(){
      video.play();
    });

    $('#stop-btn').click(function() {
      video.pause();
    });

    $('#reload-btn').click(function(){
      video.load();
    });
    
    $('#refresh-btn').click(function(){
        window.location.reload(true);
    })
        
  // on submit button click show canvas.
    $('#btnVideoSubmit').click(function() {
      
        console.log('-------On Execute Button Click-------');
        console.log(width + ' ' + height);
        console.log('video after sbmit: ', video);
        // $('.processed-video-loader').show();
                
        if (($('#selectVideoFile').val() !== '') && (file_ext === 'mp4')){
                        
            $('.caption-text-video-processed').show();
            $('#canvas').show();
            $('#videoBtn').show(200);
            
            image_bg = new Image();
            image_bg.onload = function(){
                drawVideoIntoCanvas();
            };
            image_bg.src = 'https://www.ehotelsasia.com/wp-content/uploads/2018/10/Black-Background-DX58.jpg';
            console.log('image_bg src:', image_bg.src);
            

            // Loop over the drawVideoIntoCanvas function
            //drawVideoIntoCanvas(); 
        } else {
          $('#displayVideos').hide();
          alert("Please upload person video file having extension -- (.mp4)!")
        }
    })


  
/// --------------------- End -----------------------
//document.getElementById('clear').addEventListener('click', function(){
    //ctx.clearRect(image_bg, 0, 0, 640, 375);
//})

});

标签: javascripthtml5-canvashtml5-video

解决方案


推荐阅读