I need to set canvas size using code and than drawImage on this canvas. The problem is drawn image is zoomed.
code follows -
currentImageDIV = $("#cnv").css({ "position" : "relative" ,"height": 400, "width": 800,"top" :"100px" , "border": "1px solid red" });
var c = document.getElementById("cnv");
var ctx = c.getContext("2d");
ctx.imageSmoothingEnabled = false;
var img = new Image();
img.src = "/images/sample2.jpg";
img.onload = function () {
ctx.drawImage(img, 0, 0);
}
If I do not set the canvas size than image drawn as expected, not zoomed.
How can I control the canvas size without drawImage zoomed image ?
I found out that if I hard code the width and height of the canvas tag than no zooming is taking place.
Another solution for this is to set the width and height using prop rather than css (e.g. $("#cnv").prop({"width": 800, "height": 600});)
Related
This question already has answers here:
Canvas is stretched when using CSS but normal with "width" / "height" properties
(10 answers)
Closed 4 years ago.
I have a fairly simple test, a 400 x 400 white image with text on it saying "1" over and over again.
I draw it on a fairly simple 1000 x 1000 canvas, trying to resize it to 100 x 100.
var image = new Image();
document.body.appendChild(image);
image.addEventListener("load",function (event) {
var image1 = event.target;
var tempCanvas = window.document.createElement("canvas");
tempCanvas.style.width = "1000px";
tempCanvas.style.height = "1000px";
tempCanvas.style.background = "rgba(0, 0, 0, 0.1)";
document.body.appendChild(tempCanvas);
tempCanvas.getContext("2d").drawImage(image1, 0, 0, 100, 100);
});
image.src = "1.png";
But despite all that being squares, I end up with an odd-looking, deformed, weirdly scaled result that's rectangular, low quality, and without having any of its dimensions being 100px.
On the left, you can see the original image, on the right, that's the top left corner of my canvas.
If you want the original image, here it is: https://i.stack.imgur.com/yDkLx.png
What am I missing?
Try setting the width and height values on the canvas element prior to the drawImage(), rather than relying on the styles as you are.
Setting the width and height attributes corresponds to setting the dimensions of that canvas element.
Once you've defined the dimensions of a canvas element, the rendering behavior of the canvas becomes much more predicatable:
var image = new Image();
document.body.appendChild(image);
image.addEventListener("load",function (event) {
var image1 = event.target;
var tempCanvas = window.document.createElement("canvas");
//tempCanvas.style.width = "400px";
//tempCanvas.style.height = "400px";
tempCanvas.style.background = "rgba(0, 0, 0, 0.1)";
tempCanvas.width = 100;
tempCanvas.height = 100;
document.body.appendChild(tempCanvas);
tempCanvas.getContext("2d").drawImage(image1, 0, 0, 100, 100);
});
image.src = "https://puu.sh/C4HE2/d96b531d08.png";
canvas {
border:1px solid blue;
}
img {
border:1px solid red;
}
The code snippet above shows the original source image with red border, and the down-scaled canvas rendered image with blue border - hope this helps!
thank you for taking a look.
What I am trying to do here is... load image from computer (by using FileReader), put img tag's src to the file. Then draw canvas with that image.
function previewFile(){
var preview = document.querySelector('img'); //selects the query named img
var file = document.querySelector('input[type=file]').files[0]; //sames as here
var reader = new FileReader();
reader.onload = function () {
preview.src = reader.result;
drawCanvas();
}
if (file) {
reader.readAsDataURL(file); //reads the data as a URL
} else {
preview.src = "sample.jpg";
}
}
previewFile(); //calls the function named previewFile
window.onload = function () {drawCanvas(); };
function drawCanvas() {
var img = document.querySelector("img");
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
ctx.filter = window.getComputedStyle(document.querySelector("img")).filter;
ctx.drawImage(img, 0, 0);
}
Problem is when I load another image file. It loads in the canvas, but not fit in the canvas size. It keeps the original image size and "part" of the image is shown in the canvas.
In order to solve it, I tried following:
ctx.drawImage(img, 0, 0, document.getElementById('canvas').width,
document.getElementById('canvas').height);
It works, however the image quality becomes really bad... since it is not original image size. It is adjusted to the certain height and forced to be resized.
All I want to do is... keep the original canvas size (width: some px; height: auto), so when I load the image, it fits to the canvas width and adjusted height.
Would you please help me? Thank you.
Added
I researched myself and found following:
I came up with an idea - change the image size first based on the current width of the canvas.
var img = document.querySelector("img");
var canvas = document.getElementById("image");
var ratio = img.height / img.width;
img.width = canvas.offsetWidth;
img.height = img.width * ratio;
Then draw with the edited image.
var ctx = canvas.getContext('2d');
ctx.filter = window.getComputedStyle(img).filter;
ctx.drawImage(img, 0, 0, img.width, img.height);
Then I found the problem. I checked "img.height" variable is 199px. But canvas's height becomes 150px somehow. I checked and there is no css applied to the canvas at all.
So this time, I set canvas width, before drawImage().
ctx.canvas.width = img.width;
ctx.canvas.height = img.height;
ctx.filter = window.getComputedStyle(img).filter;
ctx.drawImage(img, 0, 0);
And again, the original image coming back... and "part" of the image is shown in the canvas. The canvas's size is what I wanted though...
Thank you so much for taking a look the issue. Especially #Kaiido who tried to help. Thank you. I am really new to this stackoverflow... so I didn't know how to create demo.
I found the solution. Well... it was really basic knowledge of the Canvas,,, but I think many people will forget / miss following:
var ctx = canvas.getContext('2d');
ctx.canvas.width = 1000;
ctx.canvas.height = 1000;
ctx.drawImage(img, 0, 0, 800, 800);
ctx.canvas.width is canvas's width. ctx.canvas.height is canvas's height.
In drawImage, those 800s are width and height of the image will be drawn, not the canvas's size!! So if you set... let's say 1000, 1000 in drawImage, the image will be resized to the size and it will be drawn into the canvas. If it is bigger than the canvas size, it will show only "part" of your image.
So what I did was... get the div width size where I want to put my canvas. Then calculate the ratio of the image first ( ratio = image's height / image's width ). Then set canvas size to following ( ctx.canvas.width = div width size, ctx.canvas.height = div width size * ratio ). Then draw canvas with canva's width and height ( ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height) ).
Hope this helps someone new like me :) Thank you.
This is pretty simple!
try this.
getting the ratio, setting the height, drawing the image
var ratio = img.naturalWidth / img.naturalHeight;
var width = canvas.width;
var height = width / ratio;
ctx.drawImage(img, 0, 0, width, height);
this worked for me, try this.
see the line
var width = canvas.width;
you can replace the canvas.width by any other value.
On load of my image I:
var img = new Image();
img.src = e.target.result;
var canvas = $('#test-canvas')[0];
$('#test-canvas').width(img.width);
$('#test-canvas').height(img.height);
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
But the image is drawn larger than it's original size? I've tried a few images, same problem.
What's the fix?
jQuery will resize the element through CSS, which won't actually change the canvas internal height and width. This will resize the actual canvas element.
var canvas = document.GetElementById('test-canvas');
canvas.width = img.width;
canvas.height = img.height;
jsFiddle (http://jsfiddle.net/L0drfwgL/) just show it drawing it to scale, and resizing the canvas item itself.
It looks like you are pulling the image from an image element on load. You can use the src from the image element rather than recreating an image object and then get the image width/height from the element to draw the image to canvas.
<script>
$(document).ready(function(){
$('#testImg').on('load',function(){
var image = document.getElementById('testImg');
var canvas = document.getElementById('test-canvas');
canvas.width = image.width;
canvas.height = image.height;
var ctx=canvas.getContext("2d");
ctx.drawImage(image,0,0);
})
});
</script>
/** with vue3 -(to fix drawing canvas image is larger than actual image size **/
const captureImage = () => {
let width = video.value.getBoundingClientRect().width;
let height = video.value.getBoundingClientRect().height;
let context = canvas.value.getContext('2d')
canvas.value.width = width
canvas.value.height = height
context.drawImage(video.value, 0, 0, width, height)
}
I'm trying to load an image from a URL into a HTML canvas at a 1:1 scale. I load the image, and set the canvas DOM element to the appropriate dimensions, but for some reason the image in the canvas is significantly upscaled and therefore only the top left hand corner is drawn.
This is demonstrated by the following JSFiddle: http://jsfiddle.net/KdrYr/1/
var img = new Image();
var cv = document.getElementById('thecanvas');
img.src = 'http://www.photographyblogger.net/wp-content/uploads/2009/12/Picture-in-a-picture4.jpg';
img.onload = function() {
var ctx = cv.getContext('2d');
cv.style.width = img.width + 'px';
cv.style.height = img.height + 'px';
ctx.drawImage(img, 0, 0);
};
For example, I'm trying to draw this (sorry about the big images :/)
But end up with this
What could be causing this?
You need to assign the canvas actual width and height, not via its style:
cv.width = img.width;
cv.height = img.height;
Live test case.
As for the why, well, it's explained already here.
I have a simple fabric.canvas element which has a background and I have set its width and height equal to that of the above image.
and then added the cap image. the problem is that the resize controls are displaced. I have made this clear in the image too.
This is how I am adding the canvas to the page
$('#canvas_container').empty();
canvas_el = document.createElement('canvas');
canvas_el.id = "canvas";
$('#canvas_container').append(canvas_el);
canvas = new fabric.Canvas('canvas');
var img = new Image();
img.onload = function() {
canvas.setWidth(this.width);
canvas.setHeight(this.height);
canvas.renderAll()
}
img.src =$(this).attr('picUrl');
canvas.setBackgroundImage($(this).attr('picUrl'),function(){
canvas.renderAll();
});
And this is how I am adding the image
fabric.Image.fromURL('img/hat.png', function(img) {
oImg = img.set({ left: 50, top: 50, angle: 0 })
canvas.add(oImg);
canvas.renderAll();
});
I have got the answer on twitter.
I added a canvas.calcOffset() right after changing the width and height of the canvas and also adding the image.
It worked.
Try with oImg.setCoords() after canvas.add(oImg);