Blurry Image when renders canvas to png - javascript

I am going to convert html to canvas and render that canvas to png file.
It works well on well display but not work on which window.devicePixelRatio is larger than 2.
I use HTML2Canvas to render html as Canvas.
For canvas, I set imageSmoothingEnabled as false.
And set "image-rendering" style option to 'crisp-edges'.
html2canvas($('#finalImageToExport')[0], {
canvas: canvas,
scale: window.devicePixelRatio
})
In this case, the canvas width and height are multiple by window.devicePixelRatio.
So when I render this canvas to png, I get png file with originalImageWidth * devicePixelRatio width and originalImageHeight * devicePixelRatio.
I need same width and height with origin so scale it down to natural width and height.
But I get blurry Image.
How can I resolve this?

Related

How to scale canvas and keep the painted content without redraw?

I have a canvas which is 800 * 400px used to do signature, and how can I resize the canvas and signature together?
ctx.scale method only resize the canvas but the painted content will disappear.
thx!

Why fabric.js export is not the same size as the canvas size?

I have a 1500x1500 canvas with Fabric.js. On the inspector I can see a 1500x1500 canvas but also a 750x750 canvas.
Then, when I run:
canvas.toDataURL({
format: 'png'
})
The returned image has a resolution of 750x750. Shouldn't it be a 1500x1500 image? I tried to compensate it by scaling the returned image but the ratio between 1500 and 750 changes with different devices.
What am I missing? It makes no difference if a set the width and height of the canvas on the constructor or after creating it with setWidth() and setHeight().

Why do width/height element attributes render differently from inline/CSS styles?

Recently i've been coding a simple platformer in HTML5 and Js. My background image, which has a width of 600 pixels and a height of 400 pixels, is rendered differently depending on how i define the size of my canvas.
If i use element attributes and define its size like so: <canvas width="600" height="400"> i get the desired outcome; the image sits perfectly within the canvas.
On the other hand, if i define the canvas size by giving the canvas an ID and then style it within a CSS file like so: #canvas { width: 600px; height: 400px; }, or simply style it inline, the image appears stretched and simply doesn't fit properly within the canvas, although the values are identical.
Why don't these declaration methods render similarly?
There is a difference between the canvas dimensions and the canvas display size.
The HTML attributes sets the canvas dimensions, which determines how objects are measured that you draw on the canvas.
The CSS style sets the canvas display size, which determines how large the canvas is drawn in the browser. If the display size is different from the dimensions, the canvas will be stretched when drawn.
If you only define the dimensions, that will also be used as the display size, i.e. the canvas is drawn at scale 1:1.
If you only define the display size, the dimensions will get the default value 300 times 150.

Scrolling HTML5 Canvas viewport for printing

I am drawing a series of rectangles and text on an HTML5 Canvas. But this canvas will ultimately be printed. The rectangles are drawn according of the height of the paper(canvas)
The only canvas width that doesn't distort the text is the 300dpi or 2400x3300 canvas. This works well for print but its obviously huge on the screen.
I would like the user to have a scaled down version of the canvas on the left side that fits 100% height of the parent container with scroll bars for overflow.
I have tried div overflow:auto.. and this does work but its not scaled (still scrolling a huge version). So basically I would like to scale the image for the browser window but do all drawing/printing from the big canvas.
For this scenario you can use CSS rules with the canvas.
ONLINE DEMO HERE
Keep the pixel size but add the following rules to the canvas element itself (assuming the id of the canvas is canvas):
canvas.style.width = 'auto';
canvas.style.height = '100%';
or apply a CSS rule to the element via CSS and HTML:
.printCanvas {
width:auto;
height:100%;
}
and then in the HTML:
<canvas id="canvas" class="printCanvas" width="2400" height="3300"></canvas>
This should allow the browser to use the actual content of the canvas when printing even when the canvas is scaled down (like with an image).
In this example the canvas will fit the height of parent provided the parent has height defined. You can use as you already do overflow:auto to get scroll-bars.
If you want to show 50% of the canvas inside the parent just set height:200% for the canvas element and so on.
Note that you might loose some details on the screen if the canvas is scaled much but these should show on the print. This would be due to sub-pixeling which kicks in when a pixel is drawn as less than an actual pixel on the screen.

Everything inside my canvas got bigger after canvas resize

When I first started this project that I'm working on, my canvas size with 1400px wide and 480px tall. I realized that I am going to need to make the canvas the same size as the window itself later, so I did that and everything inside of the canvas zoomed in or something. I set a drawImage(); to be 300 px wide and 180 px tall, and it is a LOT bigger than that, the image is actually the same width as the canvas now. Any suggestions? Here's the link to the project:
http://brycemckenney.com/animation-app
Thank you guys!
You have set the dimensions through css, instead of the physical dimensions of the (image) canvas.
The relevant piece (for others to read in the future) of your code is:
var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext("2d");
var windowHeight = $(window).height();
var windowWidth = $(window).width();
$(canvas).css({
height: windowHeight - 8,
width: windowWidth - 8
});
Think of it like this: suppose you have a normal jpg-image.
That jpg has it's own 'physical' dimensions (aka width and height).
In both HTML and CSS you can set the dimensions (in px, percent, etc) that you'd like the browser to render (scale) the picture (hey, the picture already has a immutable size right?).
Now for canvas:
In order for canvas to have a physical width/height, you have to set the .width and .height of the canvas-element itself, either in HTML or per javascript (a side-effect is that setting the physical dimensions is that the canvas will clear itself, as per spec).
Then to scale the image (like you did with the above jpg example) you use css (again in px/percent/etc).
I think this is a clever solution by the way to add that new canvas-element to the HTML-Spec!
So, rounding up:
A canvas with a width and a height of 300 px rendered as 100% of a container (like document.body) that measures 900x900px will be scaled-up 3 times!
The reverse (scaling down) will let you draw even more crisp lines by the way!
Hope this helps your understanding!

Categories

Resources