2013-04-01 46 views
0

由於BMP文件是從底部到頂部(以像素爲單位)寫入的,因此需要反向讀取BMP文件(並刪除54個字節的標頭)。到目前爲止我的代碼:反向讀取文件

public string createNoHeaderBMP(string curBMP) //copies everything but the header from the curBMP to the tempBMP 
    { 
     string tempBMP = "C:\\TEMP.bmp"; 

     Stream inStream = File.OpenRead(curBMP); 
     BinaryReader br = new BinaryReader(inStream); 

     byte[] fullBMP = new byte[(width * height * 3) + 138]; 
     byte[] buffer = new Byte[1]; 
     long bytesRead; 
     long totalBytes = 0; 

     while ((bytesRead = br.Read(buffer, 0, 1)) > 0) 
     { 
      fullBMP[fullBMP.Length - 1 - totalBytes] = buffer[0]; 
      totalBytes++; 
     } 

     FileStream fs = new FileStream(tempBMP, FileMode.Create, FileAccess.Write); 
     fs.Write(fullBMP, 54, fullBMP.Length - 54); 
     fs.Close(); 
     fs.Dispose(); 

     return tempBMP; 
    } 

由於某種原因,不能完全做的工作,而這個結果中的圖片與右側放置在左側的一部分。爲什麼它不完全顛倒文件?此外,這些BMP文件非常大(600MB),所以我不能使用簡單的內存流並執行查找和交換操作,因爲我會得到「內存不足」異常。

+0

爲什麼你提到你無法讀取整個文件,但你只是做了?另外,不要像你那樣硬編碼數組的值。不能保證將有138個字節的標題數據。 –

+3

如果使用MemoryStream會得到一個OOM異常,那麼如何在不接收相同異常的情況下爲'fullBMP'數組分配空間? – cdhowie

+1

MemoryStream和Byte []基本上是一樣的東西,MS有一些額外的包裝,可以使它更容易處理,雖然...看到http://stackoverflow.com/questions/16939/difference-between-a-byte-array -and-memorystream和http://stackoverflow.com/questions/11828599/c-sharp-memorystream-vs-byte-array – Nevyn

回答

0

我還沒有檢查BMP規範,我對它沒有任何認識。我只是假設你說的是真的。

大多數顯示位圖的程序只是讀取標題以找出圖像的大小,然後從上到下讀取數據,而不是從下往上繪製位圖。你也可以在大多數文件中尋找。因此,您可以使用inStream並在其中尋找,而不需要將整個文件存儲在內存中。

然後,如果您可以分配一個600 MiB的字節數組(即內存中的600 MiB結構),那麼您肯定可以分配一個佔用600 MB內存空間的MemoryStream。或者,如果您得到OutOfMemoryException,那麼無論您使用的是byte[]還是MemoryStream,都會得到它。後者更容易處理。

只有當你意識到你已經將每個像素的顏色從R-G-B格式(或當前的任何其他格式)轉換爲B-G-R時,你纔會顛倒一切。我不確定BMP掃描線的方向,但是如果它們從左到右運行,那麼您的反轉位圖會使圖像水平翻轉。

您在右側顯示圖像部分的原因顯示在左側,是因爲您不能顛倒位圖的字節並期望它正確顯示。另外,繪製時可能有一條掃描線的長度錯誤。

另外,你說的標題是54字節,但你在fullBMP添加138個字節的數組大小。檢查你的常量:他們保證永不改變,然後讓他們const。他們會改變嗎?然後從位圖中讀取它們。