I am currently working on a project, where I have a locally hosted html page with a live video stream in it. I want to be able to capture a image from the video when pressing a button. The video is an html video element that gets its contents from hls.js. I already have a javascript function that is called when the button is clicked. The script uses a hidden canvas and sets its width and height to video.videoWidth and video.videoHeight. Then canvas.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); is called to get an image of the video. I then get a link to the image with canvas.toDataURL('image/png'); and pass the link to the href of an tag.
The problem is, that the resulting image always is 300x150, while the video is 1920x1080. This obviously is not what I want. I want to have an image that is the same size as the video. I dont understand whats causing this.
I have confirmed that video.videoWidth and video.videoHeight return the correct values, by printing them to console.
I am really confused, because looking on the internet and googling a lot, shows that other people are using the exact same javascript lines as I am and are apparently not having this issue.
Here is my script:
function MouseDown(){
elmnt.style.backgroundColor = "black";
var canvas = document.getElementById("canvas");
var vid = document.getElementById("video");
canvas.width = vid.videoWidth;
canvas.height = vid.videoHeight;
var ctx = canvas.getContext('2d');
ctx.drawImage(vid, 0, 0, vid.videoWidth, vid.videoHeight);
console.log("Size: " + vid.videoWidth + "x" + vid.videoHeight);
var img = canvas.toDataURL('image/png');
var newimg = img.replace(/^data:image\/png/,'data:application/octet-stream');
var a = document.getElementById("imageLink");
a.setAttribute('download', 'Drone-Image.png');
a.href = newimg;
a.click();
}
Edit: Whatever the problem was, it resolved itself. When I started the computer that hosts the page today and tried again, it just worked...
I had tried a restart of the computer yesterday, but that didn't help...
Related
Perhaps an odd use case, but assume the following code, where image1.jpg is 1920x1080:
<a href="http://example.com/dir/photos/image1.jpg" target="_blank">
<img src="http://example.com/dir/photos/image1.jpg">
</a>
As you can see, the image loads in full on the page; however, not shown above is CSS that's being used to display that image as a thumbnail on the page (say, 480 x 270).
Yes, this is a horribly unoptimized practice.
The issue I'm having is that a client has hundreds of these occurrences happening across multiple pages. I'm trying to quickly create thumbnail versions of the images exactly as they're sized on the page. Some images are wider/taller than others, and image/folder names are all over the place, so creating thumbnails of each image from the rendered page is what I need for what I would like to accomplish.
Ideally, I'm thinking of using JS (or jQuery, if anyone knows of any particular methods) to target all the images (however that needs to happen) to ultimately create and download/save thumbnails as their CSS-sized on-page representations.
I hope this question makes sense. I would be happy to clarify more if need be. Thank you for any assistance you can provide!
The following code, takes all images from a page, and scales them to the effective CSS size being used for rendering, then performs the download.
The way it works is the following:
Generates an empty canvas element
Generates an image, and loads the original image element source in it
Dumps the content of the new image in the canvas, using the original image sizes.
Dumps the content of the canvas back into the original image element
Executes the download() function (only works in chrome)
function scaleToElementSize(img){
return new Promise( (resolve,reject)=>{
// create an empty canvas and assign to it
// the rendered proportions of the provided image
let c = document.createElement('canvas');
c.height = img.height;
c.width = img.width ;
const ctx = c.getContext("2d");
// create an image element, and load the source
// image in it
let i = new Image();
i.setAttribute('crossOrigin', 'anonymous');
i.src = img.src;
// when image is loaded, copy its contenta scaled
// into the canvas, dump the resulting scaled
// image back, to the original image, and download
i.onload = ()=>{
ctx.drawImage(i, 0, 0, c.width, c.height);
img.setAttribute('filename', img.src);
img.onload = null;
img.src = c.toDataURL("image/png");
resolve();
}
});
}
function download(img){
var link = document.createElement('a');
link.download = img.getAttribute('filename');
link.href = img.src.replace("image/png", "image/octet-stream");;
link.click();
}
document.querySelectorAll('img').forEach( img=>{
img.onload= function(){
scaleToElementSize(img)
.then( ()=> download(img) )
}
})
<img src="https://placekitten.com/200/286?a.jpg" width="100">
<img src="https://placekitten.com/200/139?b.jpg" width="200">
<img src="https://placekitten.com/408/287?c.jpg" width="110">
Is there a way to detect when canvas content is loaded? What I'm trying is following. I need to print a page where in a widget is rendered a pdf document using the pdfjs library. Only the first pdf page have to be printed alongside with the content of the web page where the widget is placed. My approach was to get the canvas of the first pdf page which the pdfjs library created and put its content as source of an img element.
var content = canvas.toDataURL();
var img = document.createElement('img');
img.setAttribute('src', content);
widget.parentNode.insertBefore(img, widget);
Now if I use this as is, the image is created but is blank. If I put the code above inside setTimeout with a few seconds delay the image is rendered properly with the content of the first pdf page but this is not reliable for me. I've checked the content returned by canvas.toDataURL() in both cases and it appeared not equal so this was the reason for my conclusion that the content of the canvas was not loaded yet.
Any ideas for solution would be appreciated.
canvas will bind to the DOM like any other html tag. But your problem is image is not loading at very first time. So use onload method for loading images.
Refer HTML5 Canvas Load Image Data URL
EDIT :
drawImage() method draws an image or video onto the canvas. So use that method to draw the image on canvas.
Here is the updated code:
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(this, 10, 10); // here this = image, 10 = width of the image, 10 = height of the image
};
imageObj.src = dataURL;
For more information see here
In my android application, I have to show the images in thumbnail view with reduced size(100 KB) instead of showing it with original size(1 MB). It helps to improve the performance of my application.
How to implement this compression functionality using Ionic/ Cordova. Could you please provide some suggestion to implement this functionality.
Try this. It should work. But instead of image tag use canvas tag. Put this code in your javascript function for loading image. It compress your image to your desired dimensions.
img = new Image();
img.src = 'example.png'; // your file
img.onload = function(){
var canvas = document.getElementById('outputImage'); // id of your canvas
var ctx = canvas.getContext('2d');
canvas.width=400 // your dimensions
canvas.height=300
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
Task:
My task is to create a thumbnail generator using JavaScript without additional frameworks or server side. A user drops an image to a dropzone and a thumbnail is generated and displayed onto the screen. When you click on a thumbnail the full version of image should appear in the next tab.
Current solution:
I have used an invisible canvas element to draw the full and resized version of the image and I am saving them by using canvas.toDataURL() and attach this base64 encoding to the img and a tags.
Problem:
The problem I am facing is related to the file size of the image I can drop. Currently when I upload the image that exceeds 2 Megabytes the thumbnail is generated correctly but if I want to display the full size image Chrome or Firefox crash due to base64 length limit.
Question:
Is there any workaround to bypass base64 lenght limit?
Yes.
You should use HTMLCanvasElement.toBlob to create Blob object, and then URL.createObjectURL to create temporary URL that can be used to display image via or for downloading image.
Also take a look at MDN articles like Using object URLs to display images
window.URL = window.URL || window.webkitURL;
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#FFFFFF";
ctx.font="12px Verdana";
ctx.fillStyle = "#000000";
ctx.fillText("jpeg with",0,10);
ctx.fillText("quality 20 used",0,25);
ctx.fillText("intentionally",0,40);
ctx.moveTo(0,50);
ctx.lineTo(100,100);
ctx.stroke();
canvas.toBlob(function(blob){
var img = document.createElement('img');
var url = URL.createObjectURL(blob);
img.src = url;
img.onload = function(){
URL.revokeObjectURL(url);
}
document.body.appendChild(img);
}, "image/jpeg", 0.20);
<p>may not work on stackoverflow, try jsfiddle in this case</p>
<canvas id="canvas" width="100" height="100"/>
Please note that since canvas.toBlob accepts callback, and calling window.open from callback (rather than click event) will cause window to be blocked (read more here and here).
To bypass this you can create a blob beforehand, so when click occurs you can display image instantly.
Is there any way through any type of client side script to get an external image (ex: http://www.google.com/image.jpg) and resize it when the user copies the image so that the pasted image will be resized? And I can't get HTML5 canvas to work.
I'm working out of Dreamweaver CS5.5 and creating an Air App. The code works in live view but not when I preview the Air App. Here is the code that is not working:
function test(){
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var img = new Image();
img.onload = function(){
context.drawImage(img, 0,0);
};
img.src="image.jpg";
}
You can try drawing the image then doing img.src = canvas.toDataURL('image/png') prior to the user dragging. This will cause the canvas to output its data to the image tag. The canvas should be invisible, while the image is the visible element the user should drag.
To resize the image, specify the width and height in the drawImage.