2013-08-27 77 views
0

我有一個用例,我需要渲染位圖拼貼作爲預覽。該應用程序是作爲一個基於MVC的REST服務,我有一個相當香草實現:c中的高性能位圖繪製解決方案#

using (var bitmap = new Bitmap((int)maxWidth, (int)maxHeight)) 
{ 
using (var graphic = Graphics.FromImage(bitmap)) 
{ 
    graphic.InterpolationMode = InterpolationMode.HighQualityBicubic; 

    // now again for each mod 
    foreach (var mod in mods) 
    { 
     var frame = frames.First(f => f.Index == mod.FrameIndex); 
     var fileInfo = GetFileInfo(mod); 
     using (var modImage = Image.FromFile(fileInfo.FullName)) 
     { 
      graphic.DrawImage(modImage, (int)frame.Left, (int)frame.Top); 
     } 
    } 

    bitmap.Save(previewFileName); 
} 
} 

雖然這個代碼工作正常,它執行很差(尤其是較大的圖像)。我也願意使用第三方庫,我只需要一個更快的執行解決方案。

任何幫助將主要讚賞。

更新

要澄清的使用情況,緩存並不能幫助。這些圖像由客戶上傳,然後他們請求預覽所選拼貼。這是圖像寫入緩慢的拼貼畫。

+0

所以這是一個Web應用程序。您傳輸圖像的圖像格式是什麼?只是爲了確保只有繪圖是你的問題,而不是帶寬。一個System.Drawing.Bitmap可以是從RAW BMP到PNG,GIF,JPEG等任何東西。 –

+0

我不期望支持RAW,但所有其他人都是公平的遊戲。客戶正在上傳圖片。 – user975060

回答

0

圖像質量有多重要?如果你需要更快的結果,你應該嘗試InterpolationMode.NearestNeighbour,這應該快得多,但結果將是相當低質量的。 HeighQualityBicubic(您目前使用的)產生最好的結果,但性能最低。

+0

不幸的是,我確實需要最高的質量。 – user975060

0

如果您有一個靜態數量的縮略圖,類似於Netflix,我會在內存中創建一個保留縮略圖位圖的緩存。這甚至可能是一個靜態對象。一旦生成縮略圖,就不需要再次生成縮略圖。這將是一個更清潔的方法,而不是試圖找到一個更快的錘子每次擊中它。

例子:

if(MyThumbnailImageDictionary["whateverimageId"] != null) 
    return (Bitmap)MyThumbnailImageDictionary["whateverimageId"]; 

如果縮略圖是動態的,比如從上傳的圖片隨機用戶,則此方法將不利於爲圖像緩存將增長巨大的規模。

您可以使用下面的代碼來生成一個Thubnail,但我不知道它會如何更快是:

Image image = Image.FromFile(fileName); 
Image thumb = image.GetThumbnailImage(120, 120,()=>false, IntPtr.Zero); 
+0

我不知道這將如何幫助。這不僅僅發生一次,而是按照客戶的要求進行。每個客戶可以請求其中的多個。 – user975060

+0

我編輯了我的帖子,使優化明確的用例,以及替代方案。試試吧,讓我們知道它是怎麼回事。 –

+0

感謝您的更新,但我認爲您正試圖解決錯誤的問題。我在原帖中添加了一個解釋。我其實已經有縮略圖 – user975060

1

我剛纔意識到你正在繪製其原始大小的modImages(因爲您使用的只是左側和頂部座標的覆蓋)。如果這是你想要的,你可能也只是使用DrawImageUnscaled() - 圖形類的方法,這應該是要快得多:

var frame = frames.First(f => f.Index == mod.FrameIndex); 
    var fileInfo = GetFileInfo(mod); 
    using (var modImage = Image.FromFile(fileInfo.FullName)) 
    { 
     graphic.DrawImageUnscaled(modImage, (int)frame.Left, (int)frame.Top); 
    } 
+0

這很有趣,我會試試這個結果並回復結果... – user975060