2016-10-20 28 views
0

我有一個列表,這樣拼接在一起千里位圖

List<Bitmap> imgList = new List<Bitmap>();> 

我需要通過該列表中滾動,非常迅速,所有的圖像拼接成一個。像這樣

using (Bitmap b = new Bitmap(imgList[0].Width, imgList[0].Height * imgList.Count, System.Drawing.Imaging.PixelFormat.Format24bppRgb)) 
     { 
      using (Graphics g = Graphics.FromImage(b)) 
      { 
       for (int i=0;i<imgList.Count;i++) 
       { 
        g.DrawImage(imgList[i], 0, i * imgList[i].Height); 
       } 
      } 
      b.Save(fileName, ImageFormat.Bmp); 

     } 
     imgList.Clear() 

,我快到的問題是,圖像是2000寬2高,並有可能在陣列中30,000-100,000圖像。當我嘗試製作一個空白的位圖時,它會得到一個未找到參數的錯誤。任何幫助將不勝感激。

+0

對於100k圖像,每個圖像都是4k像素,您嘗試創建的24bpp圖像可能太大。看到這個細節:http://stackoverflow.com/questions/6333681/c-sharp-parameter-is-not-valid-creating-new-bitmap – wablab

+0

什麼是圖像的平均大小?處理後的圖像將如何「大」? – Cadburry

+0

http://stackoverflow.com/questions/465172/merging-two-images-in-c-net –

回答

1

您需要的內存塊大小爲2 x 100,000 x 20,000 x # bytes per pixel,對於每個像素24位將爲12,000,000,000字節,對於每像素32位,將爲16,000,000,000字節。換句話說,〜12GB或〜16GB。 32位地址空間對於內存量來說太小了,所以很糟糕。

還是呢?

由於您要從中創建文件,因此您應該關注file limits而不是您自己的內存限制。幸運的是,在BMP中用於圖像尺寸的整數類型的大小是32位,這意味着200,000×2,000的圖像完全在這些限制內。因此,無論您是否可以在內存中製作該映像,都可以製作該文件。

這涉及到製作自己的BMP編碼器版本。這並沒有那麼糟糕 - 它最多寫入了一個BMP標頭,一個DIB標頭(總共110個字節),然後是原始像素數據。當然,一旦完成,你將很難找到可以打開它的代碼,但這是別人的問題,對吧?

+0

您的偏移量爲10,即x 2000,而不是x 20000. 1.6 GB在64位進程中不是問題,2 GB是GDI +位圖的硬性上限。 –

+0

我會在使用瓷磚Tiff文件,因爲有應用程序可以從它們讀取非常大的圖像。 –

+0

TIFF確實是一種可能性,因爲TIFF本身可以用帶子編碼。編寫一個正確的TIFF編碼器是非常具有挑戰性的,充滿了錯誤。 – plinth