2013-04-01 47 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。他们会改变吗?然后从位图中读取它们。