这是我写的一段抽取象素点的源程序,拿去看吧!
{
DLL功能:将300DPI的BITMAP抽成100DPI的BITMAP
编 写: 2001-5-21
修 改: 2001-6-28 将功能扩展为可抽256色、24位真彩色、32位真彩色
}
uses
SysUtils,
Classes,
windows,
Graphics,
Dialogs;
{$R *.RES}
procedure TakeOut(InImgMem:TMemoryStream;var OutImgMem:TMemoryStream);stdcall;
var
MemoryStream : TMemoryStream;
bf : BITMAPFILEHEADER;
bi : BITMAPINFOHEADER;
NumColors : DWORD;
LineBytes : DWORD;
ImgSize : DWORD;
AfterSzie : DWORD;
i : DWORD;
Wr8bit : Byte;
Wr24bit : array[0..2] of byte;
Wr32bit : array[0..3] of byte;
rq : RGBQUAD;
TempBitMap1 : TBitmap;
TempBitmap2 : TBitmap;
begin
with InImgMem do
begin
Read(bf,sizeof(BITMAPFILEHEADER));
Read(bi,sizeof(BITMAPINFOHEADER));
end;
NumColors:=bi.biClrUsed;
//计算扫描行字节数
LineBytes:=(bi.biWidth*bi.biBitCount+31) div 8;
ImgSize:=LineBytes*DWORD(bi.biHeight);
//建立临时图象
MemoryStream:=TMemoryStream.Create;
try
//开始抽点
AfterSzie:=0;
I:=0;
case bi.biBitCount of
1: begin
end;
4: begin
end;
8: begin
InImgMem.Seek(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),0);
MemoryStream.Seek(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),0);
while i<ImgSize do
begin
InImgMem.Read(Wr8bit,1);
inc(AfterSzie);
InImgMem.Seek(2,soFromCurrent);
MemoryStream.Write(Wr8bit,1);
i:=i+3;
end;
//修改图象头信息
bf.bfType:=$4D42; //BM
bf.bfSize:=sizeof(bf)+AfterSzie;
bf.bfReserved1:=0;
bf.bfReserved2:=0;
bf.bfOffBits:=DWORD(sizeof(bf))+bi.biSize+DWORD(NumColors*sizeof(RGBQUAD));
//写进图象文件头的信息
MemoryStream.Seek(0,0);
MemoryStream.Write(bf,sizeof(BITMAPFILEHEADER));
//修改图形信息头结构信息
bi.biSizeImage:=AfterSzie;
bi.biHeight:=bi.biHeight;
bi.biWidth:=bi.biWidth;
//写进图象信息结构信息
MemoryStream.Write(bi,sizeof(BITMAPINFOHEADER));
//写图象颜色表信息
InImgMem.seek(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER),0);
for i:=1 to NumColors do
begin
InImgMem.Read(rq,sizeof(RGBQUAD));
MemoryStream.Write(rq,sizeof(RGBQUAD));
end;
end;
24:begin
InImgMem.Seek(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER),0);
MemoryStream.Seek(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER),0);
while i<ImgSize do
begin
InImgMem.Read(Wr24bit,sizeof(Wr24bit));
inc(AfterSzie,1);
InImgMem.Seek(2*sizeof(Wr24bit),soFromCurrent);
MemoryStream.Write(Wr24bit,sizeof(Wr24bit));
i:=i+3;
end;
//修改图象头信息
bf.bfType:=$4D42; //BM
bf.bfSize:=sizeof(bf)+AfterSzie;
bf.bfReserved1:=0;
bf.bfReserved2:=0;
bf.bfOffBits:=DWORD(sizeof(bf))+bi.biSize;
//写进图象文件头的信息
MemoryStream.Seek(0,0);
MemoryStream.Write(bf,sizeof(BITMAPFILEHEADER));
//修改图形信息头结构信息
bi.biSizeImage:=AfterSzie;
bi.biHeight:=bi.biHeight;
bi.biWidth:=bi.biWidth;
//写进图象信息结构信息
MemoryStream.Write(bi,sizeof(BITMAPINFOHEADER));
end;
32:begin
InImgMem.Seek(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER),0);
MemoryStream.Seek(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER),0);
while i<ImgSize do
begin
InImgMem.Read(Wr32bit,sizeof(Wr32bit));
inc(AfterSzie,1);
InImgMem.Seek(2*sizeof(Wr32bit),soFromCurrent);
MemoryStream.Write(Wr32bit,sizeof(Wr32bit));
i:=i+3;
end;
//修改图象头信息
bf.bfType:=$4D42; //BM
bf.bfSize:=sizeof(bf)+AfterSzie;
bf.bfReserved1:=0;
bf.bfReserved2:=0;
bf.bfOffBits:=DWORD(sizeof(bf))+bi.biSize;
//写进图象文件头的信息
MemoryStream.Seek(0,0);
MemoryStream.Write(bf,sizeof(BITMAPFILEHEADER));
//修改图形信息头结构信息
bi.biSizeImage:=AfterSzie;
bi.biHeight:=bi.biHeight;
bi.biWidth:=bi.biWidth;
//写进图象信息结构信息
MemoryStream.Write(bi,sizeof(BITMAPINFOHEADER));
end;
end;
//准备修正图形显示标志
MemoryStream.Seek(0,0);
TempBitMap1:=TBitmap.Create;
try
TempBitMap1.LoadFromStream(MemoryStream);
TempBitMap2:=TBitmap.Create;
try
TempBitMap2.Width:=TempBitMap1.Width div 3;
TempBitMap2.Height:=TempBitMap1.Height div 3;
case bi.biBitCount of
1:begin
end;
4:begin
end;
8:begin
TempBitMap2.PixelFormat:=pf8bit;
end;
24:begin
TempBitMap2.PixelFormat:=pf24bit;
end;
32:begin
TempBitMap2.PixelFormat:=pf32bit;
end;
end;
TempBitMap1.Canvas.CopyRect(Rect(0,0,TempBitMap2.Width,TempBitMap2.Height),
TempBitMap1.Canvas,
Rect(0,(TempBitMap1.Height div 3)*2,TempBitMap2.Width,TempBitMap1.Height));
TempBitMap2.Canvas.Draw(0,0,TempBitMap1);
TempBitMap2.SaveToStream(OutImgMem);
OutImgMem.Seek(0,0);
finally
TempBitMap2.Free;
end;
finally
TempBitMap1.Free;
end;
finally
MemoryStream.Free;
end;
end;
procedure TakeOutFile(InImgMem:TMemoryStream);stdcall;
var
MemoryStream : TMemoryStream;
bf : BITMAPFILEHEADER;
bi : BITMAPINFOHEADER;
NumColors : Integer;
LineBytes : DWORD;
ImgSize : DWORD;
AfterSzie : DWORD;
i : DWORD;
Wr : BYTE;
rq : RGBQUAD;
TempBitMap1 : TBitmap;
TempBitmap2 : TBitmap;
begin
with InImgMem do
begin
Read(bf,sizeof(BITMAPFILEHEADER));
Read(bi,sizeof(BITMAPINFOHEADER));
end;
NumColors:=bi.biClrUsed;
//计算扫描行字节数
LineBytes:=(bi.biWidth*bi.biBitCount+31) div 8;
ImgSize:=LineBytes*DWORD(bi.biHeight);
//建立临时图象
MemoryStream:=TMemoryStream.Create;
try
//开始抽点
AfterSzie:=0;
I:=0;
InImgMem.Seek(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),0);
MemoryStream.Seek(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),0);
while i<ImgSize do
begin
InImgMem.Read(Wr,1);
inc(AfterSzie);
InImgMem.Seek(2,soFromCurrent);
MemoryStream.Write(Wr,1);
i:=i+3;
end;
//写图象头信息
bf.bfType:=$4D42; //BM
bf.bfSize:=sizeof(bf)+AfterSzie;
bf.bfReserved1:=0;
bf.bfReserved2:=0;
bf.bfOffBits:=DWORD(sizeof(bf))+bi.biSize+DWORD(NumColors*sizeof(RGBQUAD));
MemoryStream.Position:=0;
MemoryStream.Write(bf,sizeof(BITMAPFILEHEADER));
bi.biSize:=40;
bi.biPlanes:=1;
bi.biCompression:=BI_RGB;
bi.biSizeImage:=AfterSzie;
bi.biClrImportant:=0;
bi.biHeight:=bi.biHeight;
bi.biWidth:=bi.biWidth;
MemoryStream.Write(bi,sizeof(BITMAPINFOHEADER));
//写图象颜色表
InImgMem.seek(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER),0);
for i:=0 to NumColors do
begin
InImgMem.Read(rq,sizeof(RGBQUAD));
MemoryStream.Write(rq,sizeof(RGBQUAD));
end;
MemoryStream.Position:=0;
TempBitMap1:=TBitmap.Create;
try
TempBitMap1.LoadFromStream(MemoryStream);
TempBitMap2:=TBitmap.Create;
try
TempBitMap2.Width:=TempBitMap1.Width div 3;
TempBitMap2.Height:=TempBitMap1.Height div 3;
TempBitMap2.PixelFormat:=pf8bit;
TempBitMap1.Canvas.CopyRect(Rect(0,0,TempBitMap2.Width,TempBitMap2.Height),
TempBitMap1.Canvas,
Rect(0,(TempBitMap1.Height div 3)*2,TempBitMap2.Width,TempBitMap1.Height));
TempBitMap2.Canvas.Draw(0,0,TempBitMap1);
TempBitMap2.SaveToFile('Temp.bmp');
finally
TempBitMap2.Free;
end;
finally
TempBitMap1.Free;
end;
finally
MemoryStream.Free;
end;
end;
exports
TakeOut,
TakeOutFile;
begin
end.