Take a snapshot from a data-uri video - javascript

I'm trying to get a snapshot from a video data-uri
var video = document.createElement('video');
video.src = uri;
canvas = document.createElement('canvas');
canvas.style.visibility = 'hidden';
document.body.appendChild(canvas);
var context = canvas.getContext('2d');
context.drawImage(video, 0, 0, canvas.width, canvas.height);
var snapshot = canvas.toDataURL();
But this doesn't work. Why?

Although it's a Data URI and you might expect the video to load instantly, you do need to listen for the video's canPlay event (see MDN).
function onFile(ev) {
var file = ev.target.files[0];
console.log();
var reader = new FileReader();
reader.addEventListener('load', function() {
taksVideoSnapshot(reader.result);
}, false);
reader.readAsDataURL(file);
}
function taksVideoSnapshot(videoUri) {
var video = document.createElement('video');
video.addEventListener('canplay', function() {
canvas = document.createElement('canvas');
canvas.style.visibility = 'hidden';
document.body.appendChild(canvas);
var context = canvas.getContext('2d');
context.drawImage(video, 0, 0, canvas.width, canvas.height);
var snapshot = canvas.toDataURL();
console.log('Snapshot', snapshot.length);
showThumb(snapshot);
}, false);
video.src = videoUri;
document.body.appendChild(video);
}
function showThumb(snapshot) {
var thumb = document.createElement('img');
thumb.src = snapshot;
document.body.appendChild(thumb);
}
<input type="file" onchange="onFile(event)">
Also see on JSBin.

Related

how can i put base64 image file into opencv? (javascript)

I'm trying to get random image from input video file, and then put the image into opencv to get grayScale image on the webpage.
Getting random image from video is solved by below-solution.
Javascript how to extract frame from video?
but now i'm stuck to the problem, Is it impossible to give base 64 source image file into opencv(imread, imshow, cv.cvtColor)? Please help me.
'''
//const cv = require("./js/opencv");
var video = document.createElement("video");
var image = new Image();
var canvas = document.getElementById("prevImgCanvas");
var canvas_after = document.getElementById("canvas_after");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
video.addEventListener('loadeddata', function() {
reloadRandomFrame();
}, false);
video.addEventListener('seeked', function() {
var context = canvas.getContext('2d');
context.drawImage(video, 0, 0, canvas.width, canvas.height);
const dataurl = canvas.toDataURL("image/jpeg")
image.src = dataurl;
image.onload = function(){
console.log(image);
let mat = cv.imread(image);
cv.imshow('canvasOutput', mat);
mat.delete();
};
}, false);
var playSelectedFile = function(event) {
var file = this.files[0];
var fileURL = URL.createObjectURL(file);
video.src = fileURL;
}
var input = document.getElementById('fileinput');
input.addEventListener('change', playSelectedFile, false);
function reloadRandomFrame() {
if (!isNaN(video.duration)) {
var rand = Math.round(Math.random() * video.duration * 1000) + 1;
video.currentTime = rand / 1000;
}
}
'''
let image = new Image()
image.src = 'your base64'
await new Promise(r => {
image.onload = r
})
cv.imread(image)

How to take an image of a stream and download it

I am trying to program a camera website. The stream seems to work, and I can see the canvas captures its image when it was drawn, but it seems I have a problem when it comes to changing it into an image and then downloading it. SOS
function capture() {
var canvas = document.getElementById('canvas');
var video = document.getElementById('video');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 140, 0, video.videoWidth, video.videoHeight);
var data = canvas.toDataURL();
var prev = window.location.href;
window.location.href = data.replace("image/png", "image/octet-stream");
window.location.href = prev;
Replace your code with the following, noting that 'capture.png' need to be replaced with actual file name you want to save file as. 'image/png' with mime type, and that toBlob function has a third quality parameter for when mimeType is image/jpeg or image/webp.
var canvas = document.getElementById('canvas');
var video = document.getElementById('video');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 140, 0, video.videoWidth, video.videoHeight);
var blob = canvas.toBlob(function (blob) {
var anchor = document.createElement('a');
anchor.style.display = 'none';
document.body.appendChild(anchor);
var url = window.URL.createObjectURL(blob);
anchor.href = url;
anchor.download = 'capture.png';
anchor.click();
window.setTimeout(() => {
window.URL.revokeObjectURL(url);
document.body.removeChild(anchor);
}, 100);
}, 'image/png');

pdfmake base64 image callback

I have to work with pdfmake to build a pdf preview within my laravel application. I am a javascript noob and going nuts to generate the dataURI for an image in b. Hope you can help me out.
How can I get that generated base64 into my docdefinition?
function convertImageToDataURL(src, callback, outputFormat) {
// Create an Image object
var img = new Image();
// Add CORS approval to prevent a tainted canvas
img.crossOrigin = 'Anonymous';
img.onload = function() {
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.naturalHeight;
canvas.width = this.naturalWidth;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
callback(dataURL);
// Mark the canvas to be ready for garbage
// collection
canvas = null;
};
img.src = src;
// make sure the load event fires for cached images too
if (img.complete || img.complete === undefined) {
// Flush cache
img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
// Try again
img.src = src;
}
}
convertImageToDataURL(
'{{asset('storage/'.$report->author->enterprises->first()->logo_image)}}',
function(dataUrl) {
// console.log('RESULT:', dataUrl);
// Put dataUrl into DocDefinition here!?!?
// return dataUrl is undefined
}
);`
Okay. As I said: I am a javascript noob. So I changed the script to this one:
function convertImageToDataURL(imgSrc) {
img = new Image();
img.src = imgSrc;
img.crossOrigin = "Anonymous";
var canvas = document.createElement("canvas");
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/jpg");
canvas = null;
return dataURL;
}
It might not be beautyful nor elegant, but it works for me.

I need to download the image after modification?

I have a function that change image color to black and white and I want to download the image after changed using button
function preview(file) {
if (file) {
var reader = new FileReader()
reader.readAsDataURL(file);
reader.onloadend = function () {
document.getElementById("img").src = reader.result;
document.getElementById("img").style.filter = "grayscale(100%)";
}
}
}
<input type="file" accept="image/*" onchange="preview(this.files[0])"/>
<br>
<img id="img"/>
There are two things here :
We have to wait for the img.onload function before doing something
We need to copy the filter from the image to the canvas
function downloadImage(imgNode, name = 'fileName', format = 'png') {
const canvas = document.createElement('canvas');
canvas.width = imgNode.width;
canvas.height = imgNode.height;
const context = canvas.getContext('2d');
context.filter = getComputedStyle(imgNode).filter; // Add the image filter to the canvas
imgNode.setAttribute('crossOrigin', 'anonymous');
context.drawImage(imgNode, 0, 0, canvas.width, canvas.height);
const url = canvas.toDataURL(`image/${format}`);
const anchor = document.createElement('a');
anchor.href = url;
anchor.download = `${name}.${format}`;
document.body.appendChild(anchor);
anchor.click();
}
function preview(file) {
if (file) {
var reader = new FileReader()
reader.readAsDataURL(file);
reader.onloadend = function () {
var img = new Image();
img.src = reader.result;
img.style.filter = "grayscale(100%)"; // Apply the CSS filter on the image
document.body.appendChild(img); // Display image
img.onload = function() {
downloadImage(img); // Download image
img.onload = null; // Prevent onload function called twice
};
}
}
}
<input type="file" accept="image/*" onchange="preview(this.files[0])"/>
<br/>
You can do this with Javascript:
First, draw an image in Canvas with CSS and then create anchor tag programmatically and assign click to it
function preview(file) {
if (file) {
var reader = new FileReader()
reader.readAsDataURL(file);
reader.onloadend = function() {
document.getElementById("img").src = reader.result;
var canvas = document.getElementById('cnimage');
var ctx = canvas.getContext('2d');
ctx.filter = "grayscale(100%)"
var img = document.getElementById("img");
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
anchor = document.createElement('a');
document.body.appendChild(anchor);
anchor.download = name;
var data = canvas.toDataURL("image/png");
anchor.href = data;
anchor.click();
ctx.clearRect(0, 0, canvas.width,canvas.height);
}
}
}
<input type="file" accept="image/*" onchange="preview(this.files[0])"/>
<br>
<img id="img"/>
<canvas id="cnimage" height="400px" width="400px"></canvas>

getImageData returns white image

I need to read the image data from an image object in javascript.
But my code returns always a blank array (set to 255)
<html>
<header>
</header>
<body>
<input type="file" id="imgfile" onchange="testImageData(event);" />
<canvas id="canvas1" width="640" height="480"></canvas>
<script src="./../scripts/cam.js" ></script>
</body>
</html>
Here is the script
var canvas1 = document.getElementById('canvas1');
var context1 = canvas1.getContext('2d');
function getImageData(image){
/*
returns Uint8ClampedArray object
takes an image obj
*/
var canvas = document.createElement("canvas");
canvas.height = image.height;
canvas.width = image.width;
var ctx = canvas.getContext("2d");
ctx.width = image.width;
ctx.height = image.height;
ctx.drawImage(image,0,0);
return ctx.getImageData(0, 0, ctx.width, ctx.height);
}
function testImageData(event){
var selectedFile = event.target.files[0];
var reader = new FileReader();
var img = new Image();
reader.onload = function(event) {
console.log('onload');
img.src = event.target.result;
img.onload = function(){
context1.drawImage(img, 0,0, img.width, img.height);
var imgData = getImageData(img);
// console.log(imgData);
var data = imgData.data;
for(var i = 0; i<data.length;i+=4){
console.log(data[i],data[i+1],data[i+2],data[i+3]);
}
}
};
In my understanding, the console.log should return me the data in RGBA.
But I'm just getting 255.
console.log output
EDIT:
Okay I found a work around but I don't understand why this is working.
Instead using getImageData, I get the data directly from the drawn context1.
function testImageData(event){
var selectedFile = event.target.files[0];
var reader = new FileReader();
var img = new Image();
reader.onload = function(event) {
console.log('onload');
img.src = event.target.result;
img.onload = function(){
context1.drawImage(img, 0,0, img.width, img.height);
var imgData = context1.getImageData(0,0,img.width,img.height);
var data = imgData.data;
for(var i = 0; i<data.length;i+=4){
console.log(data[i],data[i+1],data[i+2],data[i+3]);
}
}
};
So the problem must lie in creating a new canvas.
You should wait for the image to load img.onload you are waiting for the readers onload event...
you also forget to read the file... missed reader.readAsDataURL
but you don't need the filereader.
window.URL = window.URL || webkitURL
var img = new Image();
img.src = URL.createObjectURL(file)
img.onload = function(){
// put your image on the canvas
}

Categories

Resources