最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to scale (resize) image keep aspect ratio in javascript - Stack Overflow

programmeradmin3浏览0评论

I have some images with random dimension and the the question is how can I scale (resize) it to exactly 960×1280 for example in JavaScript, but keep image origin aspect ratio:

  • If the image is bigger than the expected size, it is scaled down (keeping aspect ratio) and the empty areas are filled with transparent color.
  • If the image is smaller than the expected size, it is not scaled but centered and the empty areas are filled with transparent color.

I had read some on this topic but still could not resolve the problem.

This is not working for me: How to resize images proportionally / keeping the aspect ratio?

UPDATED: Working solution here, many thank to @Mr. Polywhirl Update solution

I have some images with random dimension and the the question is how can I scale (resize) it to exactly 960×1280 for example in JavaScript, but keep image origin aspect ratio:

  • If the image is bigger than the expected size, it is scaled down (keeping aspect ratio) and the empty areas are filled with transparent color.
  • If the image is smaller than the expected size, it is not scaled but centered and the empty areas are filled with transparent color.

I had read some on this topic but still could not resolve the problem.

This is not working for me: How to resize images proportionally / keeping the aspect ratio?

UPDATED: Working solution here, many thank to @Mr. Polywhirl Update solution

Share Improve this question edited May 23, 2017 at 12:10 CommunityBot 11 silver badge asked Sep 30, 2016 at 11:50 Thien LeThien Le 1272 silver badges9 bronze badges 7
  • I'd used this method and some change to resize image to exactly expected dimension but it make image lose it ratio: link – Thien Le Commented Sep 30, 2016 at 11:54
  • Wele to SO. Please visit the help center to see what and how to ask. HINT: Post effort and code in a minimal reproducible example – mplungjan Commented Sep 30, 2016 at 11:55
  • 1 Thanks for reminding – Thien Le Commented Sep 30, 2016 at 11:59
  • What part of the link you gave failed? – mplungjan Commented Sep 30, 2016 at 12:04
  • 1 Thank you @Pete but I need to use js to do this and get the result image to be uploaded – Thien Le Commented Sep 30, 2016 at 12:28
 |  Show 2 more ments

3 Answers 3

Reset to default 2

In order to figure out the aspect ratio to use for scaling, you need to figure out which dimension is larger. One you do that, you just divide the image width/height by the viewer's width/height and that should determine the scaling factor.

Centering can be achieved by finding the offset of the scaled image within the viewer.

var ctx = document.getElementById('image-viewer').getContext('2d');
var images = [
  'http://i.imgur./5PF0Xdi.jpg',
  'http://i.imgur./po0fJFT.png',
  'http://i.imgur./Ijzdt0o.png'
];
var counter = 0;

// Load a new image after 2 seconds.
setInterval(function() {
  loadScaleAndCenterImage(ctx, images[counter++ % images.length]);
}, 2000);

function loadScaleAndCenterImage(ctx, url) {
  var imageObj = new Image();
  imageObj.onload   = function(e) {
    var ctxWidth    = ctx.canvas.width,
        ctxHeight   = ctx.canvas.height;
    var imgWidth    = imageObj.width,
        imgHeight   = imageObj.height;
    var ratioWidth  = imgWidth  / ctxWidth,
        ratioHeight = imgHeight / ctxHeight,
        ratioAspect = ratioWidth > 1 ? ratioWidth : ratioHeight > 1 ? ratioHeight : 1;
    var newWidth    = imgWidth / ratioAspect,
        newHeight   = imgHeight / ratioAspect;
    var offsetX     = (ctxWidth  / 2) - (newWidth  / 2),
        offsetY     = (ctxHeight / 2) - (newHeight / 2);
    ctx.clearRect(0, 0, ctxWidth, ctxHeight);
    ctx.drawImage(this, offsetX, offsetY, newWidth, newHeight);
  };

  imageObj.src = url;
}
#image-viewer {
  background-color: #E4E4E4;
  background-image:
    linear-gradient(45deg, #7F7F7F 25%, transparent 25%, transparent 75%, #7F7F7F 75%, #7F7F7F), 
    linear-gradient(45deg, #7F7F7F 25%, transparent 25%, transparent 75%, #7F7F7F 75%, #7F7F7F);
  background-size: 20px 20px;
  background-position: 0 0, 30px 30px
}
<canvas id="image-viewer" width="1280" height="960"></canvas>

Here is a solution. Basically its mostly css, but we use JS to get the image dimensions. If either dimension is greater than our bounds (x>960 or y>1280), set the css propeprty background-size:contain

    var onload = function () {
//grab image dimensions on load
        var w = this.width;
        var h = this.height;
        if (w > 960 || h > 1280) {
//set contain if needed
            document.getElementById(this.dataset.div)
                    .style.backgroundSize = "contain";
        }
    };
//grab all the container divs
    var divs = document.querySelectorAll('.container');
//iterate thru them
    for (i = 0; i < divs.length; i++) {
        var div = divs[i];
        var img = new Image;
//set the id of the current div as a data attribute of the img, 
//so we can reference it in the onload function
        img.dataset.div = div.id;
//apply onload function
        img.onload = onload;
//set the img src to the background image. use a quick regex to extract 
//just the img url from the whole "url(img.ext)" string
        img.src = getComputedStyle(div, 0).backgroundImage
                .match(/url\(['"]?([a-z0-9\/:.]+)['"]{0,1}/i)[1];
    }
div.container{
width:960px;
height:1280px;
border:1px solid black;
background-position:center;
background-repeat:no-repeat;
background-color:transparent;
/*background-image:url(/path/to/img.ext);*/
}
div#container-1{
background-image:url(http://i.imgur./5PF0Xdi.jpg);
}
div#container-2{
background-image:url(http://i.imgur./po0fJFT.png);
}
div#container-3{
background-image:url(http://i.imgur./Ijzdt0o.png);
}
<div class="container" id="container-1"></div>
<div class="container" id="container-2"></div>
<div class="container" id="container-3"></div>  

I wrote this function for a collage maker and it works like a charm.

Just set the variable "Size" below to whatever image sizes (Width x Height in pixels) you want to set as ideal for all your images to approach, without losing their aspect ratio.

Your images will retain their exact shape but will either shrink or grow to meet "Size".

function ScaleImage(Img){

var Size=150000, nW=Img.naturalWidth, nH=Img.naturalHeight, W=nW, H=nH, Scale=1;

if((W*H)>Size){

 while((W*H)>Size){Scale-=0.01; W=nW*Scale; H=nH*Scale;}

} else {

 while((W*H)<Size){Scale+=0.01; W=nW*Scale; H=nH*Scale;}

} 

Img.width=Math.round(W); Img.height=Math.round(H);

}

Typical usage...

<img src="apples.jpg" onload="ScaleImage(this);">
发布评论

评论列表(0)

  1. 暂无评论