I have a script that crops an image from the video stream.
let ctx = image.getContext("2d");
ctx.drawImage(results.image, croprect.x, croprect.y, croprectwidth, croprectheight, 0, 0, 300, 200);
In HTML
<div id="image-div">
<canvas id="image" width="300" height="200"></canvas>
</div>
Now I need to do some image processing manipulation with it. I do 'Save as' for the test but how to do it automatically?
I tried
const canvas = document.getElementById('image');
const dataURL = canvas.toDataURL();
console.log(dataURL);
In the console, it gives an URL but when I open it, it is just a blank (white) rectangle (correct size 300x200)
I want to save it to my local folder and to the backend later when the second step (image processing) of the script will work.
Related
It is difficult to find an app that can view WEBP images. So when you download one to your harddrive, it would probably be more convenient to download it as something more common, like a JPEG or PNG.
So is there an easy way to save a WEBP as a better file type?
I created this javascript bookmarklet that will convert a WEBP to a PNG in your browser.
It works by creating a canvas element and drawing the WEBP on the canvas. Then the original WEBP is removed, leaving only the new image. You can then right click the image and save it as a PNG.
Create a bookmark, and enter this code as the url:
javascript:
function a(){
var webp = document.getElementsByTagName("img")[0];
var canvas = document.createElement("canvas");
document.body.appendChild(canvas);
canvas.width = webp.width;
canvas.height = webp.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(webp, 0, 0);
webp.parentNode.removeChild(webp);
return;
};
a();
You then need to open the WEBP in a separate tab or window.
Then click the bookmarklet we made, and the WEBP will be replaced with a PNG which you can save.
Hopefully you found this helpful. Good day
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">
I have been trying to figure out how I could resize the canvas contents to get roughly a 100x100 thumbnail and upload it to the server. I would like to keep my existing canvas in its current size, because all these actions have to be invisible to the user.
I know I can get the contents in the current size of the canvas by using toDataURL, but how could I resize it and then upload to the server?
var image = canvas.toDataURL("image/png");
You can create canvas in your JS script (without appending it to DOM), then draw on it your content from working canvas (your image), resize it in context of your temp canvas ( Post about resizing in canvas ). And only then do canvas.toDataURL("image/png"); to get resized image. Then you send it as base64 string and save on your server as png file.
Thanks to Alexander Kremenets I managed to put together the code I needed. I used the Hermite resize from the question Alexander linked. Also combined code from other questions coming up with this:
var originalCanvas = document.getElementById("c");
// Create canvas for resizing
var resizeCanvas = document.createElement("canvas");
resizeCanvas.height = originalCanvas.height;
resizeCanvas.width = originalCanvas.width;
var resizeCtx = resizeCanvas.getContext('2d');
// Put original canvas contents to the resizing canvas
resizeCtx.drawImage(originalCanvas, 0, 0);
// Resize using Hermite resampling
resampleHermite(resizeCanvas, resizeCanvas.width, resizeCanvas.height, 150, 90);
// Use the resized image to do what you want
var image = resizeCanvas.toDataURL("image/png");
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.
I'm new to this - I just can't figure out why this isn't working. When I remove Display:none from HTML, the image works correctly so I know the path to the image is correct. But it's not drawing on the canvas. Thanks for your time.
HTML:
<canvas width="840" height="900" id="Canvas6">
Your browser does not support this feature.
</canvas>
<img src="image/logo.png" id="img1" width="825" height="272" style="display:none;">
<script type="text/javascript" src="js/main.js"></script>
Main.JS JAVASCRIPT:
var theCanvas = document.getElementById('Canvas6');
if (theCanvas && theCanvas.getContext) {
var ctx = theCanvas.getContext("2d");
if (ctx) {
//Create a variable to hold our image
var srcImg = document.getElementById("img1");
//Draw an image directly onto the canvas
ctx.drawImage(srcImg, 0,0);
//Draw a scaled down image
//drawImage(srcImg, dx, dy, dw, dh)
}
}
In html file, the first best thing you have done is used the 'script' tag right at the end of the html file.
This ensures that the "Critical Render Time" is minimized, and the display items in HTML are shown first. (Not a huge impact on this case, because here you are using the JS to draw/display, but this approach is really good when you use your js for other purposes like calculations etc., and you don't want to stop the other HTML items from displaying because of an ongoing calculation.)
Now that the canvas is ready, its time to throw the image on the canvas.
Try using the border property (style="border: 2px dotted black") to see the container area of the canvas.
Hmmm !! But the image doesn't show in canvas. WHY ??
Images(or any other files) take atleast some time to get processed. By the time they are getting processed to be loaded on the screen, your canvas is already getting displayed. Hence you see an empty canvas.
So, the solution is to make everything else wait, till the time image gets loaded.
How do we do that ? Just use the "Event Listener".
EventListener is the property of Window object. (window.addEventListener("load", some_func_to_run , false);). We generally use this, when we want our window/page/browser to wait for something, but hey , we can use it for our images as well.
var cvs = document.getElementById("canvas"); // Getting the control of the canvas
var ctx = cvs.getContext("2d"); //Getting the control of the useful HTML object getContext . This object brings in a lot of useful methods like drawImage, fillRect etc.
//create images
var bg = new Image(); // Creating image objects
bg.src = "images/bg.png"; //Setting the source file
//create images ends
//load images first
bg.addEventListener("load" , draw , false); //**IMPORTANT : Just remove this line and you will start facing this problem of empty canvas again
//loading images ends
function draw() {
ctx.drawImage(bg,0,0); // Putting the image and its coordinates on the canvas
}
draw(); // Calling the draw function to put the image on canvas
<html>
<body>
<canvas id="canvas" width="288" height="512" style="border: 2px dotted black"> </canvas>
<script src="flappyBird.js"></script>
</body>
</html>
So, it all about using Event Listener and asking everything to wait till the image gets loaded.
Hope this help. :)
If you try to place an image on a Canvas before it has loaded, it will not show. It is not like the img tag that will show the image whenever it loads. I surrounded your JS with an onload and it worked for me.
document.getElementById("img1").onload = function() { /* Your JS */ };
You have to wait for the image to load before you can draw it on the canvas, so set your drawing code to run on the window load event (by which time all images are loaded). Also, you don't need to include the markup for the image on the page, where you have to then prevent it from displaying with CSS. You can just create the image object and set the source attribute in the javascript. For example:
var img = document.createElement('img');
img.src = 'image/logo.png';
window.addEventListener('load', function(){
var theCanvas = document.getElementById('Canvas6');
if (theCanvas && theCanvas.getContext) {
var ctx = theCanvas.getContext("2d");
if (ctx) {
ctx.drawImage(img, 0,0);
}
}
});