I'm trying to do something very simple. I want to take an image from a document. Draw it to the screen. And be able to resize this image's height and width to what ever I choose.
What I have now doesn't change the size at all.
What am I doing wrong? I don't want to use anything but Javascript for this.
var ctx = document.getElementById('mycanvas').getContext('2d');
var img = new Image();
function draw(){
img.onload = function(){
ctx.drawImage(img,100,100);
};
img.style.height = '300px';
img.style.width = '300px';
img.src = "test.png";
}
draw();
context.drawImage has additional arguments that do the resizing for you:
var img=new Image();
img.onload=function(){
var scaleFactor=2.00;
ctx.drawImage(
img,
100,100,
img.width*scaleFactor,img.height*scaleFactor
);
}
img.src='test.png'
Related
I have 2 canvases, I save the first one as a dataURL, and then try to display it on a second canvas.
I tried many things but nothing shows up.
Here is my code.
How can I fix that ?
image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
var compCanvas = document.getElementById("final-composition");
var ctx = compCanvas.getContext("2d");
var img = new Image;
img.src = image;
img.width = compCanvas.width;
img.height = compCanvas.height;
img.onload = function(){
ctx.drawImage(img,0,0);
};
I am making a photo editor, where you have the option to upload an image that will be drawn on a canvas. I let the user upload a new image without refreshing the website. However, the second time you try to upload a different image, the whole image won't be drawn on the canvas. The only part that will be drawn is the size of the image that the user uploaded before that. This is pretty weird as a new size is set every time the user uploads a new image.
After some trial and error, I found out that the new canvas size is actually set to the size of the image that is uploaded. However, it still doesn't draw the whole image, even though it is specified that the image should be drawn at the size of the canvas. Therefore, it is a problem lying in the line that draws the image, and not the part that sets the size of canvas. I tried drawing the image twice instead of once just to see what would happen. It actually worked, even though the the two lines for drawing the image are identical. I found this pretty strange, and I feel like this is not the right way to fix it.
Here is the part of the code that loads the image:
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');
var img;
var ratio;
var overlay = document.getElementById("overlay")
canvas.width = 400;
function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
img = new Image();
img.onload = function(){
ratio = this.height / this.width;
canvas.height = canvas.width * ratio;
ctx.drawImage(img,0,0,canvas.width, canvas.height);
}
overlay.style = "display: none;"
img.src = event.target.result;
window.onbeforeunload = function() {
return true;
};
}
reader.readAsDataURL(e.target.files[0]);
}
canvas { border: 1px solid; }
<input type="file" id="imageLoader">
<canvas id="imageCanvas"></canvas>
<div id="overlay">Unrelated overlay...</div>
The behavior you're getting is not weird but makes perfect sense because you’re supposed to adjust the size of the canvas to the NATURAL dimesnions of the image loaded each time!
What makes you think that the canvas automatically adjusts itself to any image loaded?
You need to do this with every new image load...
canvas.width=img.naturalWidth;
canvas.height=img.naturalHeight;
canvas.style.transform='scale(0.5,0.5)';
After some time, I found out that I had to use clearRect before redrawing the image.
Now the JavaScript code looks like this:
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');
var img;
var ratio;
var overlay = document.getElementById("overlay")
canvas.width = 400;
function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
img = new Image();
img.onload = function(){
ratio = this.height / this.width;
canvas.height = canvas.width * ratio;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img,0,0,canvas.width, canvas.height);
}
overlay.style = "display: none;"
img.src = event.target.result;
window.onbeforeunload = function() {
return true;
};
}
reader.readAsDataURL(e.target.files[0]);
}
I have two main questions. I'm trying to resize a base64 image according to the answer in
JavaScript reduce the size and quality of image with based64 encoded code
This seemed simple enough, except for the fact that I need to get only the base64 string from that function, without the data:image... header.
I tried to modify the function like this:
function resizeBase64Img(base64, width, height) {
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
var context = canvas.getContext("2d");
var deferred = $.Deferred();
$("<img/>").attr("src", "data:image/gif;base64," + base64).load(function () {
context.scale(width / this.width, height / this.height);
context.drawImage(this, 0, 0);
deferred.resolve($("<img/>").attr("src", canvas.toDataURL()));
});
var result = canvas.toDataURL();
return result.substr(result.indexOf(",") + 1)
}
which returns a base64 string. This string is corrupted, and it never displays correctly. Why is this happening and how can I fix it?
The other question is, is there a way to resize the image based on percentage and not on pixel size?
Thanks
I ended up rewriting the function based on another canvas function I found. This function takes the src of a base64 img, modifies the size and assigns the result in base64 to another element:
function resizeBase64Img(url, width, height) {
var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.onload = function () {
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.scale(width/this.width, height/this.height);
ctx.drawImage(this, 0, 0);
result=canvas.toDataURL();
$('#ASSIGNEDELEMENT').val(result.substr(result.indexOf(",") + 1));
};
img.src = url;
}
And it should be invoked like this:
resizeBase64Img($('#image').attr('src'),300,300);
This Javascript code draw part of the image on the canvas:
var img = document.getElementById('img');
var canvas = document.getElementById('can');
//canvas.width = img.width;
//canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
But when I uncomment the middle lines to set the canvas width and height, the drawImage() does not work.
What should I check in order to find the problem?
You need to wait for the browser to load the image.
Use onload event if image was not yet loaded and change your code to something like this:
var img = document.getElementById('img');
var canvas = document.getElementById('can');
var ctx = canvas.getContext("2d");
var callback = function(image) {
if(!image) image = this;
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(image, 0, 0);
}
if(img.complete) { //check if image was already loaded by the browser
callback(img);
}else {
img.onload = callback;
}
See this working demo
var img = document.getElementById('img');
Try naming the variable something else. Also make sure some image is loaded.
Try my fiddle http://jsfiddle.net/aliasm2k/tAum2/ for more ideas
The width and height image attributes aren't set until the image is loaded, so i propose you to put your code in onLoad() image event.
I know I can do this using javascript:
var ctx = getCanvas('testCanvas').getContext('2d'); // get Canvas context
var img = new Image();
img.src = 'test.png';
img.onload = function(){
ctx.drawImage(img, 200, 200); // x, y, width, height
}
But how to draw existing tag to canvas:
In html:
<img src='test.png'>
Why I want to do this? I want to optimize image loading using pagespeed
The very first google hit for your question is promising:
var c=document.getElementById("testCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("existingHTMLImageElementId");
ctx.drawImage(img,10,10);
See w3Schools
Try
var canvas=document.getElementById("test");
var ctx=canvas.getContext("2d");
var img=document.getElementById("imgID");
ctx.drawImage(img,10,10);
assuming that your has the id #image, you could use
var img = document.getElementById("image");
var ctx = getCanvas('testCanvas').getContext('2d'); // get Canvas context
img.onload = function(){
ctx.drawImage(img, 200, 200); // x, y, width, height
}
Suppose you have an <img> tag with id of image. You can obtain the image reference by using the getElementById method. Something like the following:
var img = document.getElementById("image");
Then using your code above.
You can give the image src to your new image
var ctx = getCanvas('testCanvas').getContext('2d'); // get Canvas context
var img = new Image();
img.src = document.getElementById('testImage').src;
img.onload = function(){
ctx.drawImage(img, 200, 200); // x, y, width, height
}
add id to your image element
<img src='test.png' id="testImage">