通过文件流读取单色灰度图(8位)未压缩的,有画板数据,原图片文件像素数据结尾还多20个字节,通过像素数据索引画板,bitmap显示颜色也不对。
struct fileHead
{
UInt16 fileType;
UInt32 fileSize;
UInt16 keepword1;
UInt16 keepword2;
public UInt32 fileOffset;
static public UInt16 BM_FILE_BIT_LENGTH = 14;
public fileHead(Byte[] fileHead) {
fileType = BitConverter.ToUInt16(fileHead, 0);
fileSize = BitConverter.ToUInt32(fileHead, 2);
keepword1 = BitConverter.ToUInt16(fileHead, 6);
keepword2 = BitConverter.ToUInt16(fileHead, 8);
fileOffset = BitConverter.ToUInt32(fileHead, 10);
}
}
struct bmpInfo
{
public UInt32 bmpInfoSize;
public UInt32 bmpWidth;
public UInt32 bmpHeight;
UInt16 bmpColorPane;
public UInt16 bmpColorDeep;
UInt32 bmpCompresType;
UInt32 bmpCompresSize;
UInt32 bmpRevolutionS;
UInt32 bmpRevolutionC;
UInt32 bmpColorIndex;
UInt32 bmpColorIndexSS;
public bmpInfo(Byte[] fileHead) {
bmpInfoSize = BitConverter.ToUInt32(fileHead, 0);
bmpWidth = BitConverter.ToUInt32(fileHead, 4);
bmpHeight = BitConverter.ToUInt32(fileHead, 8);
bmpColorPane = BitConverter.ToUInt16(fileHead, 12);
bmpColorDeep = BitConverter.ToUInt16(fileHead, 14);
bmpCompresType = BitConverter.ToUInt32(fileHead, 16);
bmpCompresSize = BitConverter.ToUInt32(fileHead, 20);
bmpRevolutionS = BitConverter.ToUInt32(fileHead, 24);
bmpRevolutionC = BitConverter.ToUInt32(fileHead, 28);
bmpColorIndex = BitConverter.ToUInt32(fileHead, 32);
bmpColorIndexSS = BitConverter.ToUInt32(fileHead, 36);
}
}
class BmpImage
{
public fileHead bmpFileHead;
public bmpInfo bmpImageInfo;
private Byte[] bmpImageDataBitBuff;
private Byte[] bmpImageColorPBuff;
private UInt32[] colorP;
private UInt32[,] imageMap;
public BmpImage(Stream bmpFileStream) {
bmpFileStream.Position = 0;
BinaryReader bitread = new BinaryReader(bmpFileStream);
Byte[] fileHeadbuff = bitread.ReadBytes(14);
Byte[] bmpInfobuff = bitread.ReadBytes(40);
bmpFileHead = new fileHead(fileHeadbuff);
bmpImageInfo = new bmpInfo(bmpInfobuff);
if (bmpFileHead.fileOffset > 54)
{
UInt32 colorPSize = bmpFileHead.fileOffset - bmpImageInfo.bmpInfoSize - fileHead.BM_FILE_BIT_LENGTH;
bmpImageColorPBuff = new Byte[colorPSize];
bmpFileStream.Position = bmpImageInfo.bmpInfoSize + fileHead.BM_FILE_BIT_LENGTH;
bmpImageColorPBuff = bitread.ReadBytes((int)colorPSize);
double colorSum = Math.Pow(2, bmpImageInfo.bmpColorDeep);
colorP = new UInt32[(long)colorSum];
for (long i = 0; i < (long)colorSum; i++)
{
int startbitidx = (int)i * 4;
if(startbitidx<bmpImageColorPBuff.Length){
UInt32 color = BitConverter.ToUInt32(bmpImageColorPBuff, startbitidx);
colorP[i] = color;
//Console.WriteLine( colorP[i].ToString("X"));
}
}
}
else
{
bmpImageColorPBuff = null;
colorP = null;
}
bmpFileStream.Position = bmpFileHead.fileOffset;
long bmpDataSize = bmpFileStream.Length - bmpFileHead.fileOffset - 20 ;
bmpImageDataBitBuff = new Byte[bmpDataSize];
bmpImageDataBitBuff = bitread.ReadBytes((int)bmpDataSize);
Byte[] lastbit = bitread.ReadBytes(20);
imageMap = new UInt32[bmpImageInfo.bmpHeight,bmpImageInfo.bmpWidth];
for (UInt32 height = bmpImageInfo.bmpHeight; height > 0; height--)
{
for (UInt32 width = 0; width < bmpImageInfo.bmpWidth; width++)
{
UInt32 curr = height - 1;
imageMap[curr, width] = bmpImageDataBitBuff[curr * bmpImageInfo.bmpWidth + width];
}
}
bitread.Close();
bmpFileStream.Close();
}
public void drowBitmap(Bitmap mimage){
for (UInt32 height = bmpImageInfo.bmpHeight; height > 0; height--)
{
for (UInt32 width = 0; width < bmpImageInfo.bmpWidth; width++)
{
UInt32 curr = height - 1;
int colorIdex = (int)imageMap[curr, width];
UInt32 onep = colorP[colorIdex];
UInt32 A = onep & 255;
onep >>= 8;
UInt32 B = onep & 255;
onep >>= 8;
UInt32 G = onep & 255;
onep >>= 8;
UInt32 R = onep & 255;
mimage.SetPixel((int)width, (int)curr, Color.FromArgb((int)A, (int)R, (int)G, (int)B));
}
}
}
}