Reputation: 85
I'm drawing an image uploaded by the user on an HTML5 canvas of fixed height and width which can be dragged and resized via mouse.Now I am preserving the aspect ratio of the image with the help of the following draw function.
if(image){
const scaleX = CANVAS_WIDTH / image?.width;
const scaleY = CANVAS_HEIGHT / image?.height;
const scale = Math.min(scaleX, scaleY);
// Calculate the new dimensions of the image
const newWidth = image?.width * scale;
const newHeight = image?.height * scale;
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw the image on the canvas
setImageRight((CANVAS_WIDTH + newWidth) / 2);
setImageBottom((CANVAS_HEIGHT + newHeight) / 2);
ctx.drawImage(image, (CANVAS_WIDTH - newWidth) / 2, (CANVAS_HEIGHT - newHeight) / 2, newWidth, newHeight);
}
Here image is a part of a useState hook which I'm setting with the following code
useEffect(() => {
// Load the image onto the canvas
const image = new Image();
image.src = URL.createObjectURL(props.imageFile);
image.onload = () => {
setImage(image);
setImageWidth(image.width);
setImageHeight(image.height);
};
}, [props.imageFile]);
useEffect(() => {
if(image)
drawImage(true,false);
}, [image])
Now even though the aspect ratio of the initial image rendered on the canvas is preserved, the image quality is seriously affected. What can I do to preserve the image quality or reduce the degree to which the image quality is degrading? I am new to HTML5 Canvas methods. So any help would be appreciated greatly
The first one is the image I am drawing on the canvas. The second one is the image Photoroom is drawing onto their canvas. You can notice the difference in quality even though both the images, as well as the canvas, are of similar dimensions.
Upvotes: 0
Views: 753
Reputation: 11
It's because you’re just doing it all wrong!
Here’s how to properly load images into canvas in top quality and with the aspect ratio preserved.
I'll also demonstrate proper image scaling further down.
var Cx=C.getContext('2d');
Cx.imageSmoothingEnabled=true; Cx.imageSmoothingQuality='high'; // <-- these two are important for image quality
var I=new Image(); I.crossOrigin='anonymous'; I.src=ImgPath;
I.onload=function(){
C.width=this.naturalWidth; C.height=this.naturalHeight; // <-- these two are important for preserving the aspct ratio
Cx.drawImage(this,0,0,C.width,C.height);
};
How to properly scale images as you load them into canvas... (replace the relevant line above with this)
C.width=Math.round(this.naturalWidth*Scale); // it's important to round potential fractions off
C.height=Math.round(this.naturalHeight*Scale);
NB: Typical Scale values are... 0.5, 0.25, 0.75, 1.25 etc
Upvotes: 1
Reputation: 1
Its depend on you HTML5 canvas resolution [width x height] and also depend on ctx.drawImage() functions width x height.
Just increase width x height resolution of ctx.drawImage() function and see results.
Upvotes: 0