2013-03-05 75 views
2

我想要的解決方案是從給定數量的尺寸中選擇最佳擬合圖像尺寸。逼近擬合圖像尺寸

鑑於一些相當隨機的決議,我想找到一個圖像的大小盡可能接近我的首選大小。

假設我想使用圖像尺寸寬x高(preferredImageSize)。

例如:320x200的

假設我有我的處置(availableImageSize)以下圖像尺寸寬度1 X height1,寬度2 X身高2,...(也許多達10點不同的大小)。

例子:474x272,474x310,264x150,226x128,640x365,474x410,小480x276,256x144,160x90,320x182,640x365,192x108,240x137,小480x276

對於開發一些通用的方法,使preferredImageSize可變我想找到一個很好的解決方案,計算速度相當快,但也會導致在屏幕上看起來不錯

我定義看起來不錯屏幕上,因爲這是一個圖像:

  1. 幾乎不放大的
  2. 作爲接近給定縱橫比(preferredImageSize.width/preferredImageSize.height)儘可能
  3. 可以是重按比例縮小
  4. 可能會以非常小的量裁剪/拉伸

我的初始(相當平凡)的方法:

運行一次可用的圖像大小,找到最小寬度增量(abs(preferredImageSize.width - availableImageSize.width))。然後選擇具有最小增量的圖像(bestFitWidth)。

那肯定是解決問題的一種方式,但絕對不符合我的看起來不錯,屏幕上的希望。

任何提示,無論文本,來源或鏈接是否真棒。噢,如果你認爲我的要求(又名希望)已經領先進入錯誤的方向,繼續前進,讓我知道...


編輯:增加了裁剪和拉伸的選擇 - 我這,害怕會使問題更難解決。所以如果需要的話,不要把它排除在外。

+0

不知道爲什麼人們低估了你的問題...我覺得這很好... +1 – 2013-03-05 23:07:37

+0

我同意。我認爲這是一個體面的問題。 – 2013-03-05 23:18:37

回答

3

簡單的「如果/那麼」的方法:

我會做兩件事情:

  1. 既然你寧願不高檔,但與降頻轉換(我覺得這是不錯的選擇)OK ,切勿使用比您的目標小的源圖像,除非沒有可用的圖像。
  2. 由於「沉重」縮小比例沒問題,我會嘗試從儘可能小的可接受圖像開始,找到與縱橫比儘可能接近的圖像,然後逐漸放大圖像。

把它放在一起,首先扔掉列表中所有小於你的目標的圖像。然後,從剩下的最小圖像開始,並檢查其對目標的高寬比。如果不匹配是可接受的(您需要量化),請使用圖像,否則轉到下一個更大的圖像。如果您找不到任何可接受的,請使用最匹配的那個。

如果您已經拋出所有圖像小於您的目標,您可能會以任何方式看起來很糟糕的圖像,但你應該嘗試是否更糟糕的使用圖像,需要更多放大,還是使用更糟糕的縱橫比匹配的圖像更糟糕。

您需要考慮的另一件事是您是否想要拉伸或裁剪圖像以匹配您的目標長寬比。

更復雜的定量方法:

最靈活的方式,不過,將自己定義爲「懲罰」功能,取決於大小不匹配,縱橫比不匹配,然後找到源形象,給你最低的「懲罰」。這是你目前完成的,你已經將你的罰款函數定義爲abs(preferredImageSize.width - availableImageSize.width)。你可以用的東西去一個稍微複雜一點,像例如:

width_diff = preferredImageSize.width - availableImageSize.width 
height_diff = preferredImageSize.height - availableImageSize.height 
if (width_diff > 0) width_penalty = upscale_penalty * width_diff 
       else width_penalty = downscale_penalty * width_diff 
if (height_diff > 0) height_penalty = upscale_penalty * height_diff 
       else height_penalty = downscale_penalty * height_diff 
aspect_penalty = ((preferredImageSize.width/preferredImageSize.height) - 
        (availableImageSize.width/availableImageSize.height)) * stretch_penalty; 
total_penalty = width_penalty + height_penalty + aspect_penalty; 

現在你可以用3個數字upscale_penaltydownscale_penalty玩,stretch_penalty給這三個質量降低操作不同的重要性。試試幾個組合,看看哪個最好。

+0

我的確喜歡這種方法。我想引入一點權重並玩其價值實際上可能會有訣竅。謝謝! +1 – Till 2013-03-05 23:38:26

+0

現在我實現了一個遵循加權誤差計算思路的解決方案。爲了規範化寬度/高度誤差,我將它們按照它們的首選寬度/高度進行劃分(不完全確定這是否是一個好主意)。選擇的權重是; 'upscaleWe​​ight = 3.0f,downscalingWeight = 0.1f,aspectRatioWeight = 2.0f;'。總體而言,我認爲現在的結果非常好。此外,我添加了一個動態計算模式,以確保我只在給出新大小作爲輸入值時才執行此計算。再次感謝!! – Till 2013-03-06 02:32:58

+0

很高興能幫到你! :) – 2013-03-06 02:38:58