我需要编程浏览一些特殊格式的图片,这些图片的格式同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你.