1

我试图找出答案,但我做不到。

例如,一张图像241x76总共有18,316 pixels (241 * 76). 调整大小的规则是,像素数量不能通过10,000。那么,我怎样才能获得保持纵横比并小于10,000像素的新尺寸?

4

5 回答 5

6

伪代码:

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)
于 2012-04-11T14:07:07.293 回答
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 的答案中的图形代码而不损失任何质量

编辑:计算纵横比实际上在这里无关紧要,因为我们已经通过总像素比的(平方根)来缩放宽度和高度。您可以使用它来计算newWidth基于newHeight(或反之亦然),但这不是必需的。

于 2012-04-11T15:33:41.930 回答
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

于 2016-06-10T14:49:36.727 回答
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)
于 2021-05-16T04:15:07.560 回答
-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,您可以计算另一个维度, (given: new_height) new_width = floor(new_height * r)
(given: new_width) new_height = floor(new_width / r)

由于裁剪了值(地板函数),两对维度的比率与原始比率的接近程度可能有所不同;你会选择更好的一对。

于 2012-04-11T15:31:35.043 回答