Sounav Saha
Sounav Saha

Reputation: 85

Image Quality decreases when drawn on HTML5 Canvas - Next JS

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

Edit: This is how an uploaded image looks like when I draw it on the HTML canvas.

This is how an uploaded image looks like when Photoroom draws it onto the HTML canvas. You can notice the difference in quality between the two even though both are using similar dimensions of canvas as well as image.

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

Answers (2)

passingThrough
passingThrough

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

Muneeb Ahmad
Muneeb Ahmad

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

Related Questions