如何在JavaScript中按比例缩放(调整大小)图像

6

我有一些大小不确定的图片,现在的问题是如何通过JavaScript将它们缩放(调整大小)为确切的960×1280,同时保持原始图片的长宽比:

  • 如果图片大于期望大小,则按比例缩小并用透明颜色填充空白区域。
  • 如果图片小于期望大小,则不进行缩放但将其居中,并用透明颜色填充空白区域。

我已经阅读了一些相关主题,但仍然无法解决问题。

以下方法对我无效:How to resize images proportionally / keeping the aspect ratio?

更新:感谢 @Mr. Polywhirl 提供的方案,可行的解决方法在这里:Update solution


我使用了这种方法并进行了一些更改,将图像调整为完全符合预期尺寸,但它会使图像失去其比例:链接 - Thien Le
欢迎来到SO。请访问[帮助]以了解如何提问和提问内容。提示:在[mcve]中发布代码和努力。 - mplungjan
1
谢谢提醒。 - Thien Le
你提供的链接哪个部分出了问题? - mplungjan
谢谢 @Pete,但我需要使用 JavaScript 来完成这个任务并获取结果图像进行上传。 - Thien Le
显示剩余2条评论
3个回答

2
为了确定缩放时要使用的纵横比,您需要确定哪个尺寸更大。一旦找到,您只需将图像宽度/高度除以查看者的宽度/高度即可确定缩放因子。通过找到缩放后的图像在查看器中的偏移量,可以实现居中。

var ctx = document.getElementById('image-viewer').getContext('2d');
var images = [
  'http://i.imgur.com/5PF0Xdi.jpg',
  'http://i.imgur.com/po0fJFT.png',
  'http://i.imgur.com/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>


谢谢,我会尝试您的解决方案。 - Thien Le

0

这里有一个解决方案。基本上它主要是CSS,但我们使用JS来获取图像尺寸。如果任何一个尺寸大于我们的边界(x>960或y>1280),则设置CSS属性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.com/5PF0Xdi.jpg);
}
div#container-2{
background-image:url(http://i.imgur.com/po0fJFT.png);
}
div#container-3{
background-image:url(http://i.imgur.com/Ijzdt0o.png);
}
<div class="container" id="container-1"></div>
<div class="container" id="container-2"></div>
<div class="container" id="container-3"></div>  


0
我为一个拼贴制作工具编写了这个函数,而且它非常好用。
只需将下方的变量“Size”设置为您想要设置为所有图像理想尺寸的图像尺寸(以像素为单位的宽度x高度),而不会失去其长宽比即可。
您的图片将保持其确切形状,但会缩小或扩大以达到“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);

}

典型的使用方法...

<img src="apples.jpg" onload="ScaleImage(this);">

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接