在允许的像素限制内最大化图像比例?

时间:2011-07-27 02:17:37

标签: math scale

我正在尝试最大化图像的比例,以便尽可能多地使用允许的像素限制。

我使用的语言是ActionScript 3.0,但这个问题纯粹与数学有关,不幸的是我不是抽屉里最清晰的计算器。

来自BitmapData上的ActionScript 3.0文档:

  

BitmapData对象的最大大小为8,191像素宽或   高度,总像素数不能超过16,777,215   像素。 (因此,如果BitmapData对象的宽度为8,191像素,则只能   是2,048像素高。)

所以首先我将我的图像资源加载到程序中并确定它的最大可扩展性如下:

const MAX_BITMAP_MEASUREMENT:Number = 8191;
const MAX_BITMAP_PIXELS:Number = 16777215;

var maximumScaleProperty:Number = Math.sqrt(MAX_BITMAP_PIXELS / (image.width * image.height));

这适用于大多数图像,但是对于比它们更宽的图像(例如全景图像)而言,它会成为问题。

例如,我有一个1928 width x 451 height的图像。使用上面的等式来确定它的最大可扩展性,它将返回4.392564519715899

var maximumScaleProperty:Number = Math.sqrt(16777215 / (1928 * 451));
//returns 4.392564519715899

但是,如果我现在实际按4.392564519715899缩放此图像,而像素总数在MAX_BITMAP_PIXELS(16,777,215)范围内,则图像宽度变得太大而不能适合一侧允许的最大值(8191) :

Pixels:  (1928 * 4.392564519715899) * (451 * 4.392564519715899) = 1677215; //good
height:  (451 * 4.392564519715899) = 1981; //good
width:   (1928 * 4.392564519715899) = 8469; //bad - greater than 8191

所以为了尝试补救(读取火车残骸)这个问题,我首先评估图像的最长边是否乘以初始maximumScale是否大于8191(为简单起见,我只关注宽度更长)目前)。然后我将图像的最长边指定为8191,并将最短边(高度)减去图像宽度溢出允许像素的百分比

//  Evaluate to see if it's too big and reajust if it is:
if  (Math.max(imageWidth * maximumScaleProperty, imageHeight * maximumScaleProperty) > MAX_BITMAP_MEASUREMENT)
{
    var percentReduction:Number = 1.0 - MAX_BITMAP_MEASUREMENT / (Math.max(imageWidth, imageHeight) * maximumScaleProperty);
    maximumScaleProperty = Math.sqrt(MAX_BITMAP_PIXELS / (MAX_BITMAP_MEASUREMENT * (image.height - image.height * percentReduction)));
}

虽然这样做有效,但它会降低可扩展性,因此不会使用最大可用像素数。

在这种特定情况下,初始可伸缩性是在4.392564519715899计算的,但是因为边太长,可伸缩性一直降低到2.1669422014011723,但这太过分了。基于在我的程序中手动缩放它,接近3.9 or 4.0的东西将使用最大量而不会被切断。

我方程中的问题在哪里?

2 个答案:

答案 0 :(得分:1)

因此,您希望在以下约束下最大化比例(s)(其中h =图像高度,w =图像宽度)

maximize s
such that

s*h*s*w <= 16777215
s*h     <= 8191
s*w     <= 8191
s       >= 0

让我们重新排列您的约束并让n = h*w

s <= sqrt(16777215/n)
s <= 8191 / h
s <= 8191 / w

请注意,我们选择第一个约束的正根,因为s必须为正。

因此,s = min( sqrt( 16777215 / n),8191 / h , 8191 / w)

实施例

使用h = 1928, w = 451的示例,我们有:

s = min( sqrt( 16777215 / n),8191 / h , 8191 / w)
  = min(4.3926,4.2484,18.1619)
  = 4.2484

最大化缩放高度。

答案 1 :(得分:1)

使用最后一个例子,     8191 / 8469~ = 0.9671744007556972 因此,您将宽度设置为8191,然后将高度乘以0.9671744007556972     = ~1916

1916 * 8191 ~= 15,693,956

我认为你可以在不失宽高比的情况下接近极限。

如果您不关心纵横比(也就是说,您想要在一个轴上拉伸),那么您已经将宽度设置为8191,因此将高度设置为2048,这将导致完全限制。