如何按比例调整图像大小/保持纵横比?
Posted
技术标签:
【中文标题】如何按比例调整图像大小/保持纵横比?【英文标题】:How to resize images proportionally / keeping the aspect ratio? 【发布时间】:2011-04-27 16:13:17 【问题描述】:我有尺寸很大的图像,我想用 jQuery 缩小它们,同时保持比例受到限制,即相同的纵横比。
谁能给我一些代码,或者解释一下逻辑?
【问题讨论】:
你能详细说明为什么必须使用 jQuery 吗?有一个纯 CSS 的解决方案(参见 my answer):将其max-width
和 max-height
设置为 100%
。
以防万一有人不知道,如果您只设置图像的一个维度(宽度或高度),它会按比例调整大小。自网络诞生之日起,情况就一直如此。例如:<img src='image.jpg' width=200>
另外,您可以考虑使用slimmage.js 之类的东西来节省带宽和移动设备内存。
【参考方案1】:
看看http://ericjuden.com/2009/07/jquery-image-resize/的这段代码
$(document).ready(function()
$('.story-small img').each(function()
var maxWidth = 100; // Max width for the image
var maxHeight = 100; // Max height for the image
var ratio = 0; // Used for aspect ratio
var width = $(this).width(); // Current image width
var height = $(this).height(); // Current image height
// Check if the current width is larger than the max
if(width > maxWidth)
ratio = maxWidth / width; // get ratio for scaling image
$(this).css("width", maxWidth); // Set new width
$(this).css("height", height * ratio); // Scale height based on ratio
height = height * ratio; // Reset height to match scaled image
width = width * ratio; // Reset width to match scaled image
// Check if current height is larger than max
if(height > maxHeight)
ratio = maxHeight / height; // get ratio for scaling image
$(this).css("height", maxHeight); // Set new height
$(this).css("width", width * ratio); // Scale width based on ratio
width = width * ratio; // Reset width to match scaled image
height = height * ratio; // Reset height to match scaled image
);
);
【讨论】:
抱歉,遗漏了一些数学逻辑……当您需要全部增加时(假设您要增加 maxHeight)怎么办? 这可以单独使用 CSS 完成吗? (最大宽度、高度:自动等?) 不确定为什么需要 jQuery。在客户端按比例缩小图像可以使用 CSS 完成,而且很简单:只需将其max-width
和 max-height
设置为 100%
。 jsfiddle.net/9EQ5c
由于 IF 语句,这不能用 CSS 完成。我相信重点是填写缩略图。如果图像太高,它必须是最大宽度,如果图像太宽,它必须是最大高度。如果你做 CSS max-width, max-height,你会得到带有空格而不是完全填充的缩略图
这段代码是否会导致浏览器出现问题、崩溃或变慢??【参考方案2】:
如果图像是成比例的,那么此代码将用图像填充包装器。如果图像不成比例,则额外的宽度/高度将被裁剪。
<script type="text/javascript">
$(function()
$('#slider img').each(function()
var ReqWidth = 1000; // Max width for the image
var ReqHeight = 300; // Max height for the image
var width = $(this).width(); // Current image width
var height = $(this).height(); // Current image height
// Check if the current width is larger than the max
if (width > height && height < ReqHeight)
$(this).css("min-height", ReqHeight); // Set new height
else
if (width > height && width < ReqWidth)
$(this).css("min-width", ReqWidth); // Set new width
else
if (width > height && width > ReqWidth)
$(this).css("max-width", ReqWidth); // Set new width
else
(height > width && width < ReqWidth)
$(this).css("min-width", ReqWidth); // Set new width
);
);
</script>
【讨论】:
【参考方案3】:$('#productThumb img').each(function()
var maxWidth = 140; // Max width for the image
var maxHeight = 140; // Max height for the image
var ratio = 0; // Used for aspect ratio
var width = $(this).width(); // Current image width
var height = $(this).height(); // Current image height
// Check if the current width is larger than the max
if(width > height)
height = ( height / width ) * maxHeight;
else if(height > width)
maxWidth = (width/height)* maxWidth;
$(this).css("width", maxWidth); // Set new width
$(this).css("height", maxHeight); // Scale height based on ratio
);
【讨论】:
请考虑在回答帖子时添加解释,而不仅仅是代码。【参考方案4】:这个问题有4个参数
-
当前图像宽度 iX
当前图像高度 iY
目标视口宽度 cX
目标视口高度 cY
并且有3个不同的条件参数
-
cX > cY ?
iX > cX ?
iY > cY ?
解决方案
-
找到目标视口 F 的较小边
找到当前视口 L 较大的一侧
找出 F/L = 因子的因子
将当前端口的两边乘以因子,即fX = iX * 因子; fY = iY * 因子
这就是你需要做的。
//Pseudo code
iX;//current width of image in the client
iY;//current height of image in the client
cX;//configured width
cY;//configured height
fX;//final width
fY;//final height
1. check if iX,iY,cX,cY values are >0 and all values are not empty or not junk
2. lE = iX > iY ? iX: iY; //long edge
3. if ( cX < cY )
then
4. factor = cX/lE;
else
5. factor = cY/lE;
6. fX = iX * factor ; fY = iY * factor ;
这是一个成熟的论坛,我不会给你代码:)
【讨论】:
发布这背后的方法很棒,但我标记你并没有通过发布代码来真正帮助用户。好像有点碍事 "谁能给我一些代码,或者解释一下逻辑?" - 很明显,他可以只向他解释方法。就个人而言,我认为这将是帮助某人更好的方式,帮助他们理解方法而不是让他们复制和粘贴代码。 @JessMcintosh,可惜对原始问题的大量编辑使您的评论脱离了上下文:)【参考方案5】:其实我刚刚遇到这个问题,我发现的解决方案出奇的简单和奇怪
$("#someimage").css(height:<some new height>)
奇迹般地,图像被调整到新的高度并保持相同的比例!
【讨论】:
我认为这很有用 - 但我想如果非常非常宽,它不会限制图像到最大宽度...... 这个东西在你不设置其他属性时有效。 (在这种情况下是宽度)【参考方案6】:如果我正确理解了这个问题,那么您甚至不需要 jQuery。仅使用 CSS 即可在客户端按比例缩小图像:只需将其 max-width
和 max-height
设置为 100%
。
<div style="height: 100px">
<img src="http://www.getdigital.de/images/produkte/t4/t4_css_sucks2.jpg"
style="max-height: 100%; max-width: 100%">
</div>
这是小提琴:http://jsfiddle.net/9EQ5c/
【讨论】:
这是一个比上面更容易的答案。谢谢。顺便说一句,您是如何获得“我的答案”链接以向下滚动到您的帖子的? @SnareChops:它只是一个html anchor。 @SnareChops:如果您使用答案下方“分享”链接给出的链接,它也会滚动到答案。 @Flimm 因为跨度不显示:默认阻止。只需添加 display: 块,或将其设为 div。 在我的例子中,IMG 是用 WordPress 渲染的,所以它设置了宽度和高度。在 CSS 中,我还必须设置width: auto; height: auto;
才能让您的代码运行 :)【参考方案7】:
我觉得这真的是cool method:
/**
* Conserve aspect ratio of the original region. Useful when shrinking/enlarging
* images to fit into a certain area.
*
* @param Number srcWidth width of source image
* @param Number srcHeight height of source image
* @param Number maxWidth maximum available width
* @param Number maxHeight maximum available height
* @return Object width, height
*/
function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight)
var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
return width: srcWidth*ratio, height: srcHeight*ratio ;
【讨论】:
非常优秀的答案!如果高度和宽度都较大,则正确答案会平展。真的,很好,小胡子也很漂亮。 +1 非常简洁。声明function calculateAspectRatioFit(dimensions) /* then use such as dimensions.maxWidth , dimensions.srcWidth ...*/
之类的函数,然后调用function( maxWidth: someWidth, srcWidth: someOtherWith, maxHeight: someHeight, srcHeight: someOtherHeight );
之类的呢?这对于避免参数顺序问题很有用。
那将是理想的@AdrienBe,但这个问题在一年多前就得到了回答,我认为它很简单,可以适应个人定制。 :)
你说得对@sstauross,十进制像素可以有一点unexpected results。然而,在我的用例中,它可以忽略不计。我想Math.floor
将真正有助于 pixel perfect 设计:-)
这是处理这个问题的绝妙方法!我对 img 元素进行了一些调整 + 防止放大图像:function imgSizeFit(img, maxWidth, maxHeight) var ratio = Math.min(1, maxWidth / img.naturalWidth, maxHeight / img.naturalHeight); img.style.width = img.naturalWidth * ratio + 'px'; img.style.height = img.naturalHeight * ratio + 'px';
【参考方案8】:
这对我来说完全适用于可拖动项目 - aspectRatio:true
.appendTo(divwrapper).resizable(
aspectRatio: true,
handles: 'se',
stop: resizestop
)
【讨论】:
【参考方案9】:没有额外的临时变量或括号。
var width= $(this).width(), height= $(this).height()
, maxWidth=100, maxHeight= 100;
if(width > maxWidth)
height = Math.floor( maxWidth * height / width );
width = maxWidth
if(height > maxHeight)
width = Math.floor( maxHeight * width / height );
height = maxHeight;
记住:搜索引擎不喜欢它,如果宽度和高度属性不适合图像,但他们不知道 JS。
【讨论】:
【参考方案10】:<img src="/path/to/pic.jpg" style="max-width:XXXpx; max-height:YYYpx;" >
有帮助吗?
浏览器将负责保持纵横比不变。
即max-width
在图像宽度大于高度时启动,其高度将按比例计算。同样max-height
将在高度大于宽度时生效。
您不需要任何 jQuery 或 javascript。
ie7+等浏览器支持(http://caniuse.com/minmaxwh)。
【讨论】:
很棒的提示!只是将 CSS 放在 CSS 文件中,而不是直接放在 html 代码中。 我认为这样做的问题是,当您在页面加载之前不知道最大宽度和最大高度是多少时,它将不起作用。这就是需要 JS 解决方案的原因。这通常是响应式网站的情况。【参考方案11】:经过反复试验,我得出了这个解决方案:
function center(img)
var div = img.parentNode;
var divW = parseInt(div.style.width);
var divH = parseInt(div.style.height);
var srcW = img.width;
var srcH = img.height;
var ratio = Math.min(divW/srcW, divH/srcH);
var newW = img.width * ratio;
var newH = img.height * ratio;
img.style.width = newW + "px";
img.style.height = newH + "px";
img.style.marginTop = (divH-newH)/2 + "px";
img.style.marginLeft = (divW-newW)/2 + "px";
【讨论】:
【参考方案12】:为了确定aspect ratio,您需要有一个目标比率。
function getHeight(length, ratio)
var height = ((length)/(Math.sqrt((Math.pow(ratio, 2)+1))));
return Math.round(height);
function getWidth(length, ratio)
var width = ((length)/(Math.sqrt((1)/(Math.pow(ratio, 2)+1))));
return Math.round(width);
在本例中,我使用16:10
,因为这是典型的显示器纵横比。
var ratio = (16/10);
var height = getHeight(300,ratio);
var width = getWidth(height,ratio);
console.log(height);
console.log(width);
上面的结果将是 147
和 300
【讨论】:
考虑到,300=对角线宽度=高度*比例和高度和你说的一样【参考方案13】:这应该适用于所有可能比例的图像
$(document).ready(function()
$('.list img').each(function()
var maxWidth = 100;
var maxHeight = 100;
var width = $(this).width();
var height = $(this).height();
var ratioW = maxWidth / width; // Width ratio
var ratioH = maxHeight / height; // Height ratio
// If height ratio is bigger then we need to scale height
if(ratioH > ratioW)
$(this).css("width", maxWidth);
$(this).css("height", height * ratioW); // Scale height according to width ratio
else // otherwise we scale width
$(this).css("height", maxHeight);
$(this).css("width", height * ratioH); // according to height ratio
);
);
【讨论】:
【参考方案14】:可以使用 CSS 实现调整大小(保持纵横比)。 这是受 Dan Dascalescu 的帖子启发而进一步简化的答案。
http://jsbin.com/viqare
img
max-width:200px;
/*Or define max-height*/
<img src="http://e1.365dm.com/13/07/4-3/20/alastair-cook-ashes-profile_2967773.jpg" />
<img src="http://e1.365dm.com/13/07/4-3/20/usman-khawaja-australia-profile_2974601.jpg" />
【讨论】:
【参考方案15】:这是对 Mehdiway 答案的更正。新的宽度和/或高度未设置为最大值。以下是一个很好的测试用例(1768 x 1075 像素):http://spacecoastsports.com/wp-content/uploads/2014/06/sportsballs1.png。 (由于缺乏声望点,我无法在上面对此发表评论。)
// Make sure image doesn't exceed 100x100 pixels
// note: takes jQuery img object not HTML: so width is a function
// not a property.
function resize_image (image)
var maxWidth = 100; // Max width for the image
var maxHeight = 100; // Max height for the image
var ratio = 0; // Used for aspect ratio
// Get current dimensions
var width = image.width()
var height = image.height();
console.log("dimensions: " + width + "x" + height);
// If the current width is larger than the max, scale height
// to ratio of max width to current and then set width to max.
if (width > maxWidth)
console.log("Shrinking width (and scaling height)")
ratio = maxWidth / width;
height = height * ratio;
width = maxWidth;
image.css("width", width);
image.css("height", height);
console.log("new dimensions: " + width + "x" + height);
// If the current height is larger than the max, scale width
// to ratio of max height to current and then set height to max.
if (height > maxHeight)
console.log("Shrinking height (and scaling width)")
ratio = maxHeight / height;
width = width * ratio;
height = maxHeight;
image.css("width", width);
image.css("height", height);
console.log("new dimensions: " + width + "x" + height);
【讨论】:
【参考方案16】:2 步:
步骤1)计算Image的原始宽度/原始高度的比率。
步骤 2)将 original_width/original_height 比率乘以新的所需高度,得到新高度对应的新宽度。
【讨论】:
【参考方案17】:这个问题可以通过 CSS 解决。
.image
max-width:*px;
【讨论】:
【参考方案18】:调整大小以适应容器,获取比例因子,缩小百分比控制
$(function ()
let ParentHeight = 200;
let ParentWidth = 300;
$("#Parent").width(ParentWidth).height(ParentHeight);
$("#ParentHeight").html(ParentHeight);
$("#ParentWidth").html(ParentWidth);
var RatioOfParent = ParentHeight / ParentWidth;
$("#ParentAspectRatio").html(RatioOfParent);
let ChildHeight = 2000;
let ChildWidth = 4000;
var RatioOfChild = ChildHeight / ChildWidth;
$("#ChildAspectRatio").html(RatioOfChild);
let ScaleHeight = ParentHeight / ChildHeight;
let ScaleWidth = ParentWidth / ChildWidth;
let Scale = Math.min(ScaleHeight, ScaleWidth);
$("#ScaleFactor").html(Scale);
// old scale
//ChildHeight = ChildHeight * Scale;
//ChildWidth = ChildWidth * Scale;
// reduce scale by 10%, you can change the percentage
let ScaleDownPercentage = 10;
let CalculatedScaleValue = Scale * (ScaleDownPercentage / 100);
$("#CalculatedScaleValue").html(CalculatedScaleValue);
// new scale
let NewScale = (Scale - CalculatedScaleValue);
ChildHeight = ChildHeight * NewScale;
ChildWidth = ChildWidth * NewScale;
$("#Child").width(ChildWidth).height(ChildHeight);
$("#ChildHeight").html(ChildHeight);
$("#ChildWidth").html(ChildWidth);
);
#Parent
background-color: grey;
#Child
background-color: red;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="Parent">
<div id="Child"></div>
</div>
<table>
<tr>
<td>Parent Aspect Ratio</td>
<td id="ParentAspectRatio"></td>
</tr>
<tr>
<td>Child Aspect Ratio</td>
<td id="ChildAspectRatio"></td>
</tr>
<tr>
<td>Scale Factor</td>
<td id="ScaleFactor"></td>
</tr>
<tr>
<td>Calculated Scale Value</td>
<td id="CalculatedScaleValue"></td>
</tr>
<tr>
<td>Parent Height</td>
<td id="ParentHeight"></td>
</tr>
<tr>
<td>Parent Width</td>
<td id="ParentWidth"></td>
</tr>
<tr>
<td>Child Height</td>
<td id="ChildHeight"></td>
</tr>
<tr>
<td>Child Width</td>
<td id="ChildWidth"></td>
</tr>
</table>
【讨论】:
【参考方案19】:将图像大小调整到特定百分比
// scale can be 0.40, 0.80, etc.
function imageScaler(originalHeight, originalWidth, scale)
const scaledWidth = originalWidth * scale;
const scaledHeight = (originalHeight / originalWidth) * scaledWidth;
return [scaledHeight, scaledWidth];
【讨论】:
【参考方案20】:如果您想要特定的纵横比,您可以确定宽度高度, 让你拥有一张3264×2448的图片 图片纵横比 => 2448 ÷ 3264 =0.75 现在只需检查在除法上给出 0.75 的数字。 像 16:9 => 9÷16 =0.5625(错不是0.75) 现在 4:3 =>3÷4=0.75(我们明白了) 所以原来的纵横比是4:3 现在调整图像大小 宽度=3264÷/×4 高度=2448 ÷/× 3 ÷ 用于减少 × 增加 希望你能理解并自己编写代码,这是非常有效的,因为我们只需要进行非常基本的算术运算,除法或乘法如此简单。 如果我错了,请告诉我。
【讨论】:
我无法格式化此文档,因此请有人对其进行编辑并使其可读。我不知道该怎么做,对不起以上是关于如何按比例调整图像大小/保持纵横比?的主要内容,如果未能解决你的问题,请参考以下文章
如何在保持图像纵横比的同时调整 UIButton 中的图像大小?