我试图找出答案,但我做不到。
例如,241x76
的图片总共有18,316 pixels (241 * 76)
。
调整大小规则是,像素数量无法通过10,000
。
然后,如何让新尺寸保持纵横比并且小于10,000
像素?
答案 0 :(得分:5)
伪代码:
pixels = width * height
if (pixels > 10000) then
ratio = width / height
scale = sqrt(pixels / 10000)
height2 = floor(height / scale)
width2 = floor(ratio * height / scale)
ASSERT width2 * height2 <= 10000
end if
在实施时,请记住对所有涉及ratio
和scale
的计算使用浮点数学。
的Python
import math
def capDimensions(width, height, maxPixels=10000):
pixels = width * height
if (pixels <= maxPixels):
return (width, height)
ratio = float(width) / height
scale = math.sqrt(float(pixels) / maxPixels)
height2 = int(float(height) / scale)
width2 = int(ratio * height / scale)
return (width2, height2)
答案 1 :(得分:1)
C#中的另一个函数,它接受并返回一个Image
对象:
using System.Drawing.Drawing2D;
public Image resizeMaxPixels(int maxPixelCount, Image originalImg)
{
Double pixelCount = originalImg.Width * originalImg.Height;
if (pixelCount < maxPixelCount) //no downsize needed
{
return originalImg;
}
else
{
//EDIT: not actually needed - scaleRatio takes care of this
//Double aspectRatio = originalImg.Width / originalImg.Height;
//scale varies as the square root of the ratio (width x height):
Double scaleRatio = Math.Sqrt(maxPixelCount / pixelCount);
Int32 newWidth = (Int32)(originalImg.Width * scaleRatio);
Int32 newHeight = (Int32)(originalImg.Height * scaleRatio);
Bitmap newImg = new Bitmap(newWidth, newHeight);
//this keeps the quality as good as possible when resizing
using (Graphics gr = Graphics.FromImage(newImg))
{
gr.SmoothingMode = SmoothingMode.AntiAlias;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(originalImg, new Rectangle(0, 0, newWidth, newHeight));
}
return newImg;
}
}
使用来自Resizing an Image without losing any quality
的答案的图形代码 编辑:计算宽高比实际上与此无关,因为我们已经将宽度和高度缩放了总像素比率(平方根)。您可以使用它来根据newWidth
(或反之亦然)计算newHeight
,但这不是必需的。
答案 2 :(得分:1)
Deestan的代码适用于方形图像,但在宽高比不同于1的情况下,平方根不起作用。您需要将比例缩放为宽高比除以2的幂。
观察(Python):
def capDimensions(width, height, maxPixels):
pixels = width * height
if (pixels <= maxPixels):
return (width, height)
ratio = float(width) / height
scale = (float(pixels) / maxPixels)**(width/(height*2))
height2 = round(float(height) / scale)
width2 = round(ratio * height2)
return (width2, height2)
让我们比较结果。
初始尺寸: 450x600 初始像素: 270000
我正在尝试调整大小以尽可能接近 119850 像素。
使用Deestan的算法: capDimensions:300x400 调整像素大小: 67500
使用修改后的算法: capDimensions。 332x442 调整像素大小: 82668
答案 3 :(得分:0)
这是我今天下午想出来的,当时我想自己解决数学问题,为了好玩。我的代码似乎工作正常,我测试了几种不同形状和大小的图像。确保使用浮点变量,否则数学会出错。
orig_width=1920
orig_height=1080
orig_pixels=(orig_width * orig_height)
max_pixels=180000
if (orig_pixels <= max_pixels) {
# use original image
}
else {
# scale image down
ratio=sqrt(orig_pixels / max_pixels)
new_width=floor(orig_width / ratio)
new_height=floor(orig_height / ratio)
}
1920x1080 (1.77778 ratio) becomes 565x318 (1.77673 ratio, 179,670 pixels)
1000x1000 (1.00000 ratio) becomes 424x424 (1.00000 ratio, 179,776 pixels)
200x1200 (0.16667 ratio) becomes 173x1039 (0.16651 ratio, 179,747 pixels)
答案 4 :(得分:-1)
width2 = int(ratio * height / scale)
最好是
width2 = int(ratio * height2)
因为这可能会更好地保留纵横比(因为height2已被截断)。
如果不引入另一个像'sc'这样的变量,就可以写出 new_height = floor(sqrt(m / r))
和
new_width = floor(sqrt(m * r))
给定m = max_pixels(此处:10.000),r = ratio = w / h(此处:241/76 = 3.171)
两个结果都是相互独立的!从每个new_value,您可以计算其他维度
(给定:new_height)new_width = floor(new_height * r)
(给定:new_width)new_height = floor(new_width / r)
由于剪切值(地板函数),两个维度对可能在它们的比率与原始比率的接近程度上有所不同;你会选择更好的一对。