【发布时间】:2011-04-16 01:33:13
【问题描述】:
我这里有一个 PCX 解码器,用 C# 编写,旨在返回一个 IntPtr,它指向一个未压缩字节数组(PCX 文件使用 RLE 压缩,但我的解码器应该能够处理这个问题)。我已经从文件中读取了宽度、尺寸和调色板,对于大多数图像,图像只会将文件渲染为位图,但有些无法正确渲染。图像在那里,颜色也在那里,但实际的位图看起来像是被对角线切割了 4 或 5 次并重新排列。我检查了图像中的飞机数量,bpp也很好。
我认为我的代码有问题,所以如果有人看到错误,请告诉我。
编辑 2:
正如 Guffa 指出的那样,我没有处理任何填充。谁能指出我正确的方向?
代码(抱歉,这里有很多,但它是实际的像素处理器):
IntPtr pBits;
Boolean bRepeat;
Int32 RepeatCount;
Byte ReadByte;
Int32 Row = 0;
Int32 Col = 0;
Byte[] PCXData = new Byte[BytesPerScanline * ScanLines]; //BytesPerScanline * ScanLines);
BinaryReader r = new BinaryReader(file);
r.BaseStream.Seek(128, SeekOrigin.Begin);
while (Row < ScanLines)
{
ReadByte = r.ReadByte();
bRepeat = (0xc0 == (ReadByte & 0xC0));
RepeatCount = (ReadByte & 0x3f);
if (!(Col >= BytesPerScanline))
{
if (bRepeat)
{
ReadByte = r.ReadByte();
while (RepeatCount > 0)
{
PCXData[(Row * BytesPerScanline) + Col] = ReadByte;
RepeatCount -= 1;
Col += 1;
}
}
else
{
PCXData[(Row * BytesPerScanline) + Col] = ReadByte;
Col += 1;
}
}
if (Col >= BytesPerScanline)
{
Col = 0;
Row += 1;
}
}
pBits = System.Runtime.InteropServices.Marshal.AllocHGlobal(PCXData.Length);
System.Runtime.InteropServices.Marshal.Copy(PCXData, 0, pBits, PCXData.Length);
return pBits;
【问题讨论】:
-
您的命名约定(或缺少命名约定)使代码更难阅读。您正在用匈牙利符号命名一些局部变量(在 .NET 中不鼓励这样做),以及其他局部变量,例如它们是方法。例如查看代码
ReadByte = r.Readyte(),其中对方法ReadByte的调用结果放在变量ReadByte... -
当您知道每行的迭代次数和要迭代的行数时,您使用
while循环的任何特殊原因?您应该使用for循环。 -
哦,很抱歉匈牙利符号,我不熟悉它,我不知道它不鼓励。至于循环,它不就是和'for'循环做同样的事情吗?
-
@Danel DiPaolo:这完全值得商榷,取决于具体情况、偏好和简洁性。
-
你如何使用解压后的字节?根据您对问题的描述,听起来您需要在扫描线之间进行一些填充以将每条扫描线放置在均匀的偏移量上。
标签: c# image image-processing