javascript: how does canvas.drawImage work - javascript

I'm trying to draw an image onto a canvas, like this:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("scream");
ctx.drawImage(img,0,0,100,100,0,0,200,200);
The canvas is 200px by 200px and the image is much bigger (but styled at 200px by 200px too)
As you can see in the jsfiddle the canvas doesn't show the image (I was expecting a part of the image).
My understanding of drawImage (as is described here) goes like this:
"0,0,100,100" defines a rectangle on the image which is the part that is drawn onto the canvas. 0,0 defines the top/left corner and 100,100 are the widths of the sides.
This rectangle is drawn onto the canvas inside the rectangle defined by 0,0,200,200
Any suggestions what goes wrong here ?

You image is actually 585 x 585 so what you are doing is to clip a corner from it (which is blank) and draw it onto canvas which of course won't show anything.
Scaling the image with CSS doesn't actually change its size. It only scales it for display.
So what you need to do is to use the original size of the image as basis. If you simply want to scale it down to fit in canvas you can do:
ctx.drawImage(img, 0, 0, 200, 200);
The same goes for canvas. Don't scale canvas using CSS but set the width and height properties/attributes or else the canvas will default to 300x150 (which is then scaled by your css):
<canvas width=200 height=200 ...>
Modified fiddle

Set the width and height on the canvas and draw the image at the same dimensions. Updated your fiddle - http://jsfiddle.net/FQhGg/2/
var c=document.getElementById("myCanvas"),
ctx=c.getContext("2d"),
img=document.getElementById("scream"),
width = img.width,
height = img.height;
c.width = width;
c.height = height;
ctx.drawImage(img,0,0,width,height);

Related

How can i get high resolution image from smaller canvas?

I am using one canvas in my web app and it's actual height and width are 500px. I am showing this canvas on screen as 500px square but i want image exported from this canvas as 1600px square. I have tried below code with no luck.
canvas.width = 1600;
canvas.style.width = 500;
Any help will be appreciated.
You can have the canvas display at 500px while still having a resolution of 1600px. Display size and resolution are independent. For resolution you set the canvas width and height properties. For display size you set the canvas style width and height properties.
// create a canvas or get it from the page
var canvas = document.createElement("canvas");
// set the resolution (number of pixels)
canvas.width = canvas.height = 1600;
// set the display size
canvas.style.width = canvas.style.height = "500px";
// get the rendering context
var ctx = canvas.getContext("2d");
To get the rendering to match the display size you need to scale up all rendering. You can do this by setting the transform scale to the canvas resolution divided by the display size
var scale = 1600 / 500; // get the scale that matches display size
ctx.setTransform(scale,0,0,scale,0,0);
Now when you render to the canvas you use the screen size coordinates.
ctx.fillRect(0,0,500,500); // fill all of the canvas.
ctx.fillStyle = "red"; // draw a red circle 100 display pixels in size.
ctx.beginPath();
ctx.arc(250,250,100,0,Math.PI * 2);
ctx.fill();
When you then save the canvas, what ever method you use as long as it is not screen capture the saved canvas will be 1600 by 1600 and all the rendering will be correctly positions and proportional
HTML
<canvas width="1600px" height="1600px" > </canvas>
CSS
canvas{
position :absolute;
transform:scale(0.3125);
left:-500px; //adjust
top:-350px; //adjust
}
Use transform:scale() to adjust size of your canvas
Now 1600 * 1600 will be the actual size of your canvas, so you can directly export images from your canvas
But in view it show as 500px * 500px beacuse it's scaled down, it dose not affect the image quality while exporting
Honest answer: you can't.
If you did, then you'd have found a way to losslessly compress data with less than 1/9th of the original size, and without any encoding, which is unarguably impossible.
What you can do is scale it up in a way that it at least doesn't get blurry. To do that, you need the final image to be an integer multiple of the previous canvas, so the browser won't apply anti-aliasing. Or if you want to use your own copying formula with putImageData that would get rid of anti-aliasing, you'll still get various incongruences and it would be very slow
In your case, the closest you could get is 1500x1500 ( 3*500x3*500 ). If your point was to process an image, you're not in luck, but if you just want to display something good enough, you can resort to various other tricks such as centering the canvas and using properties like box-shadow to make it clear that it's separate from the rest of the screen

Canvas Rotation+Scaling

I need to rotate an image in a canvas and simultaneously resize it to make sure that the corners of the canvas does not remain empty. The solution should be something similar to what do aviary in the "Crop, Resize & Rotate" example.
I think the solution is to combine the functions of rotation and resize of canvas, but I can not find any concrete solution to the problem and I didn't find any exaustive example on the web.
Any advice would be helpful
Thanks
I have not had a look at the example you have given but I gave a detailed answer on the problem of fitting a rotated image onto a canvas so that there is no blank spaces.
There is some math involved (go figure) but it is just basic trigonometry and I provided an explanation of how its all done. There are two solutions, one that finds the min scale that will fit the canvas for any rotation and the other the will find the min scale to fit the canvas for a particular rotation.
It is assumed that the image is centered, if not there is an easy way to adapt the code provided by supplying an abstract canvas size so that the rotated image is centered on that abstract canvas.
So if your center of image is at x = 100, y = 100 and the canvas is canvasWidth = 300, canvasHeight = 300 then just use an abstract size of absCanvasWidth = (canvasWidth - x) * 2; and then the image at x = absCanvasWidth/2 do the same for height. That will fit the rotated, translated image to fill the canvas.
The answer with the code can be found for the question After rotate, draw Image at correct position
Here's some code that might help you. This shows how to rotate an image 90 degrees clockwise, then scale it to fit in the original canvas space.
window.onload = function() {
var img = document.getElementById("myImage");
var rotatedCanvas = document.getElementById("myRotatedCanvas");
var width = rotatedCanvas.offsetWidth;
var height = rotatedCanvas.offsetHeight;
// draw the original image
var ctx = document.getElementById("myCanvas").getContext("2d");
ctx.drawImage(img, 0, 0);
// draw the rotated image
ctx = rotatedCanvas.getContext("2d");
ctx.rotate(90 * Math.PI / 180);
// the last two parameters scale the image
ctx.drawImage(img, 0, -width, height, width);
};
img {
display: none;
}
canvas {
border: 1px black solid;
}
<img src="http://imgur.com/UeMOrix.gif" id="myImage"/>
<canvas id="myCanvas" width="400" height="150"></canvas>
<br>
<canvas id="myRotatedCanvas" width="400" height="150"></canvas>

Canvas behaves oddly at different sizes

Been playing around with canvas lately, but it behaves oddly at different sizes.
Here's my code:
HTML: <canvas></canvas>
CSS: canvas { width:300px; height:50px; }
JS:
var c = document.querySelector("canvas"),
ctx = c.getContext("2d");
ctx.fillRect(10,10,50,50); // fill a 50x50 square at pos (10,10)
At canvas size 300x50, the following is drawn:
At canvas size 100x200, the following is drawn:
It's clear that one pixel does not actually mean one pixel - am I doing something wrong?
Don't use CSS to change the size of the canvas. Instead change the size of the element:
c.width=300;
c.height=50;
That's because when you resize with CSS you're "stretching" the pixels. When you change the size of the element itself, you are actually adding/subtracting pixels.

Canvas doesn't follow up resize of image?

I've got the following piece of code:
HTML
<img src="http://hollywoodteenonline.com/wp-content/uploads/2011/12/justin_bieber_someday_fragrance_dree_hemingway.jpg" id="imagem"/>
<canvas id="mycanvas">
CSS
#mycanvas{
height:200px;
width: 200px;
border: solid;
color: black;
}
#imagem{
height:200px;
width: 200px;
}
Javascript
var canvas = document.getElementById("mycanvas"),
ctx = canvas.getContext("2d"),
img = document.getElementById("imagem");
ctx.drawImage(img,0,0);
As you can see, the canvas doens't follow up the resize of the original image. As the code is written it "should" show all of the source but resized to de designated canvas. Is there any way to go around this?
Issues
First issue is that you don't set a size for your canvas element by using its properties. This is the only way you can affect the content of the canvas and not settings it means it will default to 300 x 150 pixel no matter what you set as CSS rule for it.
Second issue is that you are using CSS to the set size. This will affect the element itself, not the content of the canvas. Technically this isn't wrong in case you want to scale the canvas as an image, but it won't do anything for the canvas and the result is that you just scale the 300x150 pixels around.
The third issue, if the image is of different size than 300x150 it won't fit the canvas (too small or get cropped if too big).
Solutions
One solution is to set the size of the canvas to the size of the image and paint the image in:
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
Now you can resize the canvas (as an image using CSS) if you want.
Or you can scale the image using the size of the canvas (remove the CSS rule; and you still need to set a size for canvas):
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
LIVE DEMO HERE
You also need to take care in how you invoke your script. For images to work with canvas they need to be loaded. As they load asynchronous you need to handle load events one way or another (ie. inside a window.onload in this case).

Rectangle on HTML5 Canvas is stretched

I am working on a website and I try to get rectangles on a HTML5 canvas with javascript. Normally this is no problem but now when I make a rectangle with the width and height of 10. It seems that it makes a rectangle with the width of 10 and the height of 20.
I'm making the Rectangle like this:
var canvas = $("#canvas");
var context = canvas.get(0).getContext("2d");
context.fillRect(0, 0, 10, 10);
The div canvas is set with a width of 100% but i tried to give it a fixed width and that didn't help either.
You need to set a width and height on your canvas element, otherwise this can be the result in some browsers.
<canvas id="canvas" width="400" height="300" />
And you can not set the canvas size with CSS, this will stretch the canvas.
The default size of the canvas is 300 x 150.
You are probably using these defaults, which will make the rectangle look not square....

Categories