首页  编辑  

将已经得到的位图文件头、信息头、调色板、数据在内存中构建BMP位图

Tags: /超级猛料/Picture.图形图像编程/图片处理/   Date Created:

我需要编程浏览一些特殊格式的图片,这些图片的格式同BMP查不多,我的处理方法是将此

文件转为位图格式的临时文件temp.bmp,然后再用Image1.Picture.LoadFromFile(...)。

我知道可以Bitmap:=TBitmap.Create在内存中创建一位图,那么如何将位图文件头、信息

头、调色板、数据传过去呢?这样我就不用每次都生成临时文件那么麻烦了,直接在内存

中构建,然后调用,会方便很多!

如果能在回答的同时附带一个小的演示程序最好,只要将一个BMP文件1.bmp显示出来就行,

但记住,是要分别将BMP文件的文件头、信息头、调色板、数据传过去的方式,不要告诉我

直接Image1.Picture.LoadFromFile(1.bmp)啊!

First,你所要的只是将已有的位图数据内容加上一个头信息,那很简单,利用

TBitmapFileHeader和TBitmapInfoHeader可以很容易填写头信息,然后,用

TMemoryStream,Seek(0,soFromBeginning),先把文件和信息头写进去,然后再

写数据,那就可以LoadFromStream.

Second,将图像画到Bitmap上去,未必要逐点赋值;即便要逐点赋值,也可以做得很

快,可以参考FastBmp的直接内存读写.

抄一段我写的有关的创建设备无关位图(DIB)直接内存读写点信息给你看:

...

const hSection = 0;

type

   TFColor  = record b,g,r:Byte end;

   PFColor  =^TFColor;

   TLine    = array[0..0]of TFColor;

   PLine    =^TLine;

   TPLines  = array[0..0]of PLine;

   PPLines  =^TPLines;

...

var

     FFileHeader : TBitmapFileHeader;

     FInfoHeader : TBitmapInfoHeader;

     FInfo      : TBitmapInfo;

     FBits      : Pointer;

 Self.PixelFormat:=pf24bit;    //设定你的Bitmap都为24位真彩,统一格式.

 //Bitmap 文件头

 with FFileHeader do

 begin

   bfType        := $4D42;

   bfSize        := AWidth*AHeight*3+SizeOf(TBitmapFileHeader)+SizeOf(TBitmapInfoHeader);

   bfReserved1   := 0;

   bfReserved2   := 0;

   bfOffBits     := SizeOf(TBitmapFileHeader)+SizeOf(TBitmapInfoHeader);

 end;

 with FInfoHeader do

 begin

   biSize        := SizeOf(TBitmapInfoHeader);

   biWidth       := AWidth;

   biHeight        := AHeight;

   biPlanes        := 1;

   biBitCount        := 24;

   biCompression := BI_RGB;

   biSizeImage   := AWidth * AHeight * 3;

 end;

 FInfo.bmiHeader:=FInfoHeader;

 FMyHandle:=CreateDIBSection(0,

                  FInfo,

                  DIB_RGB_COLORS,

                  FBits,

                  hSection,

                  0);

 memDC:=GetDC(0);

 GetDIBits(memDC,Self.Handle,0,AHeight,FBits,FInfo,DIB_RGB_COLORS);

 ReleaseDC(memDC);

 最重要是两个API,分别是创建一个内存DIB并给指针FBits分配内存,下一句则是

将该DIB的内容读入FBits所指的内存区域.以后的事就简单了,对每一个点,只要

让一个指针指向所需的内存区域:

 GetMem(FPixels,AHeight * SizeOf(PLine));  //你自己定义的一个象素点指针

 RowInc := (AWidth * 3 + AWidth mod 4);    //每行都是4的整数倍个字节

 XPointer := Integer(FBits);

 for LoopI:=0 to AHeight - 1 do

 begin

  FPixels^[LoopI] := Pointer(XPointer);

  Inc(XPointer,RowInc{ + AWidth mod 4});

 end;

 {下面这一段是为了让你可以用BitBlt和StretchBlt等直接对HDC进行图像操作

  的API,也就是说可以象操作TCanvas那样进行操作,不过要记得,当所有的图像操作

 完以后,要GdiFlush才能让对应的FBits内存刷新,切记切记 }

 if FMyhDC<>0 then DeleteDC(FMyhDC);

 FMyhDC:=CreateCompatibleDC(0);

 SelectObject(FMyhDC,FMyHandle);

 有什么地方不懂的话可以去看FastBmp的源码,上面一段基本是照抄,我是用在自己

定义的扩展TBitmap类中的.希望对你有帮助.

 对了,想要FastBmp的话我可以mail你.