【问题标题】:Maximizing Image Scale Within Allowable Pixel Limit?在允许的像素限制内最大化图像比例?
【发布时间】:2011-07-27 02:17:36
【问题描述】:

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

我使用的语言是 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 的东西会使用最大量而不会被切断。

我的方程式哪里出了问题?

【问题讨论】:

    标签: math scale


    【解决方案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
    

    最大化缩放高度。

    【讨论】:

    • 我希望我有更多的数学头脑。谢谢你更优雅的解决方案,雅各布。
    • @TheDarkIn1978:谢谢,没问题:)!
    【解决方案2】:

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

    1916 * 8191 ~= 15,693,956
    

    这几乎是我认为在不损失纵横比的情况下可以达到的极限。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-22
      • 1970-01-01
      • 2020-10-12
      • 1970-01-01
      相关资源
      最近更新 更多