Home > Blockchain >  return canvas as webp image
return canvas as webp image

Time:11-04

How can I return the canvas on this function as webp image?

function capture(video) {
    if(scaleFactor == null){
        scaleFactor = 1;
    }
    //var w = video.videoWidth * scaleFactor;
    //var h = video.videoHeight * scaleFactor;
    var w = 700;
    var h = 400;
    var canvas = document.createElement('canvas');
        canvas.width  = w;
        canvas.height = h;
    var ctx = canvas.getContext('2d');
        ctx.drawImage(video, 0, 0, w, h);
        var uniq = 'img_'   (new Date()).getTime();
        canvas.setAttribute('id', uniq);
    return canvas ;
}

CodePudding user response:

Canvas has a method known as .toDataURL(type, encoderOptions).

I this case the following snippet should suffice

canvas.toDataURL('image/webp');

This will give you a data url which is a base64 encoding of the image and will look something like

data:image/webp;base64,UklGRqgCAABXRUJQVlA4WAoAAAAwAAAAxwAAYwAASUNDUBgCAAAAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANkFMUEgPAAAAAQcQEREAUKT//yWi/6lwAFZQOCBSAAAA8AcAnQEqyABkAD5tNplJpCMioSBoAIANiWlu4XXwADuh1VJsmIdVSbJiHVUmyYh1VJsmIdVSbJiHVUmyYh1VJsmIdVSbJhYAAP7/wbAAAAAAAA==

More information for this can be found on https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL

CodePudding user response:

Tainted canvases may not be exported.

This answer demonstrates the problem with using canvas to capture video thumbnail images. Videos are typically stored on some other domain. And even though you can play these videos in a <video> element and capture video thumbnails to a <canvas> element, you won't be able to export the image data.

For example, an export statement like:

let str = canvas.toDataURL("image/webp"); // or "image/png"

throws the security exception:

Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

Setting the crossorigin="anonymous" attribute of the video and canvas usually won't fix this error and may prevent the video from loading. So a prerequisite to making such a design work is store the videos on same domain or else at a CORS enabled location.

Related SO question: Tainted canvases may not be exported

Snippet

The snippet loads a video and then captures a thumbnail image as it plays. This part works as expected and displays the thumbnail on the right. Yet, when we try to use the thumbnail data the browser throws an exception.

let video = document.querySelector("video"),
  canvas = document.querySelector("canvas"),
  ctx = canvas.getContext("2d"),
  dataURL = "";

canvas.width = video.clientWidth;
canvas.height = video.clientHeight;

// auto capture video thumbnail after video starts playing

video.addEventListener("progress", function(e) {
  
  if (video.currentTime > 1 && !dataURL) {

    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
  
    // try to export the dataURL
    try {
      dataURL = canvas.toDataURL("image/webp");
      console.log("success!", dataURL);
      
    } catch (error) {
      dataURL = error.message;
      console.error(error.message);
    }
  }
});
body {
  font-family: sans-serif;
}
h5 {
  margin: 0.2rem;
}
video, canvas {
  border: 1px solid lightgray;
  margin: 0.5rem;
}
<h5>Demo - Capture video thumbnail image</h5>
<video 
  src="http://www.nasa.gov/downloadable/videos/nasa_-_targeting_mars.mp4"
  style="height:100px;width:auto;" 
  controls 
  muted 
  autoplay></video>

<canvas></canvas>

  • Related