wolfeh
wolfeh

Reputation: 686

Blazor Take Snapshot of Video Stream with Blazor/ Interact with javascript using Blazor Interop

I am new to blazor and I have a video playing in my video tag. I want to take a snapshot as a jpg or png of this video clip as a picture and save it.

I am trying to figure out how to do this with Blazor. I need help since I don't know where to start.

 <video width="320" height="240" controls>
   <source src="https://www.w3schools.com/tags/movie.mp4" type="video/mp4">
 </video>


 <button class="btn btn-success" @onclick="TakePicture">Create Profile Picture</button>
 <canvas id="PicCanvas" style="display :none"></canvas>

The System.Drawing doesn't seem to work its not references in this framework but maybe its the wrong approach. I need some guidance on what to do. Thanks

async Task TakePicture()
{
    System.Drawing.img =
  System.Drawing.Image


}

Upvotes: 1

Views: 2343

Answers (1)

Aurelien BOUDOUX
Aurelien BOUDOUX

Reputation: 306

You can achieve your need by using canvas with the following way

First, add a canvas non visible in your html and set an id to your video element

<video id="video" width="320" height="240" controls>
   <source src="https://www.w3schools.com/tags/movie.mp4" type="video/mp4">
 </video>
  <canvas id="capturedImage" width="200" height="200" style="display: none"></canvas>

Create a javascript file "interop.js" in wwwroot folder

//DrawImage
window.Snap = async (src, dest) => {
    let video = document.getElementById(src);
    let ctx = get2DContext(dest);
    ctx.drawImage(video, 0, 0, 400, 240);
}

// Get image as base64 string
window.GetImageData = async (el, format) => {
    let canvas = document.getElementById(el);
    let dataUrl = canvas.toDataURL(format);
    return dataUrl.split(',')[1];
}

// Helper functions
function get2DContext(el) {
    return document.getElementById(el).getContext('2d');
}

dont forget to register your script in _host.cshtml

<script src="interop.js"></script>

Then, in your razor page, you can make a capture like that

...
@inject IJSRuntime JsRuntime


async Task TakePicture()
{
   await JsRuntime.InvokeVoidAsync("Snap", "video", "capturedImage");
   var imageBytes = await JsRuntime.InvokeAsync<string>("GetImageData", "capturedImage", "image/jpeg");
   var data = Convert.FromBase64String(imageBytes); // get the image as byte array

}

Upvotes: 5

Related Questions