C# 如何打开二进制文件并将其存储在 16 位缓冲区中
本文关键字:缓冲区 存储 何打开 二进制文件 | 更新日期: 2023-09-27 18:37:18
我正在编写一个程序来进行一些图像处理。 我正在使用原始二进制文件,我需要将原始文件中的数据写入 16 位缓冲区。 我几乎得到了它,但我不太确定如何进行转换。 这是我到目前为止的代码:
Int16[] pixelBuffer;
String inFile;
String outFile;
/// Constructor. Allocates space for 3032x2016 16-bit values.
/// <param name="inputFile">Name of the binary input file to be read.</param>
/// <param name="outputFile">Name of the binary output file to be written.</param>
public ColorCorrector(String inputFile, String outputFile)
{
this.inFile = inputFile;
this.outFile = outputFile;
this.pixelBuffer = new Int16[6112512];
//I need to open the binary file 'inputFile' and store 16-bit values in pixelBuffer.
}
任何帮助将不胜感激!
using (var inputStream = File.Open(inputFile))
using (var reader = new BinaryReader(inputStream))
{
int index = 0;
while (inputStream.Position < inputStream.Length)
pixelBuffer[index++] = reader.ReadInt16();
}
如果你想要最好的性能,我建议你使用 FileStream 类读入一个固定大小byte[]
缓冲区(大约 64KB)。
您可以使用不安全的代码将每个缓冲区复制到Int16[]
中。只需几行即可完成复制,而且速度很快,因为不需要轮班和转换等。这只是一个紧密的复制循环。
我估计BinaryReader慢了10倍左右。现代CPU喜欢没有分支的紧密循环,而BinaryReader无法提供这一点。
如果需要全部在内存中,不妨使用原始byte[]
缓冲区。你可以假装这实际上是通过unsafe
short
/ushort
:
byte[] raw = File.ReadAllBytes(inputPath);
unsafe
{
fixed(byte* ptr = raw)
{
ushort* pixels = (ushort*)ptr;
pixels[0] = 0; // <=== your changes, etc
}
}
File.WriteAllBytes(outputPath, raw);
注意:您可能需要检查文件的字节序是什么。我在上面做了ushort
,因为ushort
对 MSB 设置的值使用"shift"操作的人来说,这不会带来更少的意外。如果它实际上并不代表一个数字(而只是:数据),通常更容易将其视为无符号。
你应该看看System.IO.BinaryReader
以及System.Drawing.Bitmap
,这些可能是你正在寻找的。
您可以从FileStream
进行BinaryReader
,并使用 ReadInt16()
方法从流中读取 16 位整数。