2

I have a base64 string for an image, which i have to display as an icon. If the dimension of an image are bigger i have to display icon maintaining aspect ratio. I have written a logic to identify if the image is landscape or portrait based on which height and width will be settled for canvas. But seems height and width of icons are not proper as i have hard coded it.

 var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); var height, width; if (this.height>this.width) { height = 50; width = 30; } else if (this.height<this.width) { height = 30; width = 50; } canvas.width = width; canvas.height = height; ctx.drawImage(image, 0, 0, this.width, this.height, 0, 0, canvas.width, canvas.height ); var scaledImage = new Image(); scaledImage.src = canvas.toDataURL(); 

Is there any way we can calculate it dynamically or any other way to preserve aspect ratio for icons.

Working Example can be found on https://codepen.io/imjaydeep/pen/ewBZRK

enter image description here

It will be fine if some space will be left on x-y axis.

4
  • of course you can calculate it dynamically but you're not giving enough information.... do you want to scale it by a certain percent? do you have a max width or height you want to scale it to? a max filesize? how do you want to scale it? Commented Jun 19, 2019 at 13:27
  • If you want to keep aspect ratio and your image doesn't fit the ratio, your image will either leave blanks or be truncated, which one do you want? Commented Jun 19, 2019 at 13:28
  • icon size is square say 75*75. if its landscape it takes all width and if its portrait it takes all height. @Iwrestledabearonce. Commented Jun 19, 2019 at 13:29
  • @Kaddath remaining area i can keep blank. Commented Jun 19, 2019 at 13:30

2 Answers 2

3

You just need to calculate the scale or ratio and multiply both dimensions by that. Here's an example function, and here's your edited codepen.

Creates trimmed, scaled image:

enter image description here

function scaleDataURL(dataURL, maxWidth, maxHeight){ return new Promise(done=>{ var img = new Image; img.onload = ()=>{ var scale, newWidth, newHeight, canvas, ctx; if(img.width < maxWidth){ scale = maxWidth / img.width; }else{ scale = maxHeight / img.height; } newWidth = img.width * scale; newHeight = img.height * scale; canvas = document.createElement('canvas'); canvas.height = newHeight; canvas.width = newWidth; ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, newWidth, newHeight); done(canvas.toDataURL()); }; img.src = dataURL; }); } 

Or, if you want the image to always be the provided dimensions with empty surrounding area, you can use this: (codepen)

Creates scaled image of exact provided dimensions:

enter image description here

function scaleDataURL(dataURL, maxWidth, maxHeight){ return new Promise(done=>{ var img = new Image; img.onload = ()=>{ var scale, newWidth, newHeight, canvas, ctx, dx, dy; if(img.width < maxWidth){ scale = maxWidth / img.width; }else{ scale = maxHeight / img.height; } newWidth = img.width * scale; newHeight = img.height * scale; canvas = document.createElement('canvas'); canvas.height = maxWidth; canvas.width = maxHeight; ctx = canvas.getContext('2d'); dx = (maxWidth - newWidth) / 2; dy = (maxHeight - newHeight) / 2; console.log(dx, dy); ctx.drawImage(img, 0, 0, img.width, img.height, dx, dy, newWidth, newHeight); done(canvas.toDataURL()); }; img.src = dataURL; }); } 
Sign up to request clarification or add additional context in comments.

1 Comment

doesn't work so well if the image width is larger than the target canvas width
0

For someone who search for a solution when the image is bigger that you need.

 function scaleDataURL(dataURL: string, maxWidth: number, maxHeight: number) { return new Promise((done) => { var img = new Image() img.onload = () => { var scale, newWidth, newHeight, canvas, ctx if (img.width > maxWidth) { scale = maxWidth / img.width } else if (img.height > maxHeight) { scale = maxHeight / img.height } else { scale = 1 } newWidth = img.width * scale newHeight = img.height * scale canvas = document.createElement('canvas') canvas.height = newHeight canvas.width = newWidth ctx = canvas.getContext('2d') console.log('img', 'scale', scale, 0, 0, img.width, img.height, 0, 0, newWidth, newHeight) ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, newWidth, newHeight) done(canvas.toDataURL()) } img.src = dataURL }) } 

Usage:

 scaleDataURL(base64data, 600, 200) .then((newBase64data) => { console.log(newBase64data) }) .catch((err) => console.log(err)) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.