求比Stretchblt方法更快的缩放算法,有的别藏着呀!(100分)

  • 主题发起人 主题发起人 3cs
  • 开始时间 开始时间
3

3cs

Unregistered / Unconfirmed
GUEST, unregistred user!
我用Stretchblt方法把一张320*240的BMP图片放大到800*600用了>100毫秒的时间,大家有没有好的算法把这个缩放的时间控制在<15毫秒以上呀?(我的本本是CPU1.2,内存是256)
 
to:MyMidas
Gdi+不熟呀,能不能给点具体的算法![:)]
 
升级下电脑就好了。[:D]
 
呵呵 是要显示视频吧,用 StretchDIBits吧。速度一流,
当然也可以用DX SHOW
 
to 张辉明:
对,我是显示视频,能不能说说StretchDibits这个函数的用法吗?
 
StretchDIBits函数的功能是拷贝一个DIB中的某矩形区域中的像素的颜色数据到指定的矩形区域中,如果目的矩形区域的大小与源区域不相同,该函数会自动地进行伸展或压缩以使之适合显示。它的原型如下:

int StretchDIBits(
HDC hdc, // 设备上下文句柄
int XDest, // 目的区域左上角X轴坐标
int YDest, // 目的区域左上角Y轴坐标
int nDestWidth, // 目的区域的宽度
int nDestHeight, // 目的区域的高度
int XSrc, // 源区域左上角X轴坐标
int YSrc, // 源区域左上角Y轴坐标
int nSrcWidth, // 源区域的宽度
int nSrcHeight, // 源区域的高度
CONST VOID *lpBits, // 指向位图的比特数据,即像素数据数组
CONST BITMAPINFO *lpBitsInfo, // 位图头部信息的指针,包含了该DIB的信息
UINT iUsage, // usage options
DWORD dwRop // raster operation code
);
这是函数原型,谁能不能给我一个实例,谢谢!
 
我用Stretchblt函数的例子:
var
bmp1,bmp2:TBitmap;
begin
bmp1:=TBitmap.create;
bmp2:=TBitmap.create;
try
bmp1.loadfromfile('c:/1.bmp');
bmp2.width:=800;
bmp2.height:=600;
bmp2.PixelFormat:=Bmp1.PixelFormat;
SetStretchBltMode(Bmp2.Canvas.Handle,STRETCH_DELETESCANS);
Stretchblt(Bmp2.Canvas.Handle,0,0,800,600,bmp1.Canvas.Handle,0,0,bmp1.Width,bmp1.Height,srccopy);
finally
bmp1.free;
bmp2.free;
end;
end;
请高手帮我改成用StretchDIBits函数实现在的方法,谢谢!
 
各种函数的性能测试。哈哈不仅教了你StretchDIBit的用法,各种函数测试也帮你做!都是我自己原创,今天拿出来晒晒,中国加油,DELPHI FANS加油。
unit MainView;

// This code was generated by the EasyMVC OTA Wizard
// www.eazisoft.com

interface
uses
Windows, Messages, SysUtils, Classes,Graphics,DrawDib,
Controls,StdCtrls,ComCtrls,ExtCtrls,Forms,patterns, Menus;

type
TViewMain = class(TFORM,IObserver)
MainMenu1: TMainMenu;
N1: TMenuItem;
N_New: TMenuItem;
N3: TMenuItem;
N_Close: TMenuItem;
N5: TMenuItem;
N_Push: TMenuItem;
N_Wood: TMenuItem;
N_Pwindows: TMenuItem;
Button1: TButton;
Timer1: TTimer;
Button2: TButton;
Image1: TImage;
Button3: TButton;
Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
procedure UpdateView(o: TObject);

public
{ Public declarations }
procedure DirectDisplay(BmpFile : String; Handle : HDC);
procedure DirectDisplay2(BmpFile : String; Handle : HDC);
procedure DirectDisplay3(BmpFile : String; Handle : HDC);
procedure SetNotifyEventHandler(ANotifyEvent: TNotifyEvent);

end;


implementation

uses DHCtrl;

{$R *.dfm}

procedure TViewMain.UpdateView(o: TObject);
begin

end;


procedure TViewMain.SetNotifyEventHandler(ANotifyEvent: TNotifyEvent);
var
i : Integer ;
begin
for i := 0 to self.ComponentCount - 1 do
begin
if Components is TMenuItem then
(Components as TMenuItem).OnClick := ANotifyEvent;
end;
end;

procedure TViewMain.Button1Click(Sender: TObject);
var
bmp : TBitmap ;
i : Integer ;
Start : DWORD ;
begin
Bmp := TBitmap.Create ;
bmp.LoadFromFile('e:/1.bmp');
Start := GetTickCount ;
for i := 0 to 5000 do
begin
bmp.Canvas.TextOut(10,10,inttostr(i));
StretchBlt(self.Canvas.Handle, 10, 10, 320,240,bmp.Canvas.Handle,0,0,320,240,self.Canvas.CopyMode);
end;
Caption := IntToStr(GetTickCount - Start);
bmp.Free ;
end;

procedure TViewMain.Button2Click(Sender: TObject);
var
start : DWORD ;
i : Integer ;
begin
start := GetTickCount ;

DirectDisplay('e:/1.bmp',image1.Canvas.Handle);
Caption := IntToStr(GetTickCount - start) ;

end;



procedure TViewMain.DirectDisplay(BmpFile: String; Handle: HDC);
var
Bmf: TBitmapFileHeader;
BitmapInfo: PBitmapInfo;
HeaderSize: Integer;
ImageSize: LongWord;
BitsMem: Pointer;
Stream: TFileStream;

i : Integer ;
begin
try
Stream := TFileStream.Create(BmpFile, fmOpenRead or fmShareDenyWrite);
Stream.ReadBuffer(Bmf, sizeof(Bmf)); //&amp;para;&amp;Aacute;&amp;Icirc;&amp;Auml;&amp;frac14;&amp;thorn;&amp;Iacute;·
ImageSize := Stream.Size - sizeof(Bmf) ;
Stream.ReadBuffer(HeaderSize, sizeof(HeaderSize));

GetMem(BitmapInfo, HeaderSize + 12 + 256 * sizeof(TRGBQuad));
Stream.ReadBuffer(Pointer(Longint(BitmapInfo) + sizeof(HeaderSize))^,
HeaderSize - sizeof(HeaderSize)); //&amp;para;&amp;Aacute;&amp;Icirc;&amp;raquo;&amp;Iacute;&amp;frac14;&amp;ETH;&amp;Aring;&amp;Iuml;&amp;cent;
BitmapInfo^.bmiHeader.biSize := HeaderSize ;

Dec(ImageSize, HeaderSize);
GetMem(BitsMem,ImageSize);
Stream.ReadBuffer(BitsMem^, ImageSize);

for i := 0 to 3000 do
begin
StretchDIBits( Handle,
0, 0,BitmapInfo^.bmiHeader.biWidth , BitmapInfo^.bmiHeader.biHeight,
0, 0, BitmapInfo^.bmiHeader.biWidth, BitmapInfo^.bmiHeader.biHeight,
BitsMem, BitmapInfo^, 0, SRCCOPY);
image1.Canvas.TextOut(10,10,inttostr(i));
Image1.Refresh ;
end;


finally
FreeMem(BitsMem);
Stream.Free ;
end;

end;

procedure TViewMain.DirectDisplay2(BmpFile: String; Handle: HDC);
var
Bmf: TBitmapFileHeader;
BitmapInfo: PBitmapInfo;
HeaderSize: Integer;
ImageSize: LongWord;
BitsMem: Pointer;
Stream: TFileStream;
HdcMem : HDC ;
HBit: hBitmap ;
i : Integer ;
begin
try
Stream := TFileStream.Create(BmpFile, fmOpenRead or fmShareDenyWrite);
Stream.ReadBuffer(Bmf, sizeof(Bmf)); //&amp;para;&amp;Aacute;&amp;Icirc;&amp;Auml;&amp;frac14;&amp;thorn;&amp;Iacute;·
ImageSize := Stream.Size - sizeof(Bmf) ;
Stream.ReadBuffer(HeaderSize, sizeof(HeaderSize));

GetMem(BitmapInfo, HeaderSize + 12 + 256 * sizeof(TRGBQuad));
Stream.ReadBuffer(Pointer(Longint(BitmapInfo) + sizeof(HeaderSize))^,
HeaderSize - sizeof(HeaderSize)); //&amp;para;&amp;Aacute;&amp;Icirc;&amp;raquo;&amp;Iacute;&amp;frac14;&amp;ETH;&amp;Aring;&amp;Iuml;&amp;cent;
BitmapInfo^.bmiHeader.biSize := HeaderSize ;

Dec(ImageSize, HeaderSize);
GetMem(BitsMem,ImageSize);
Stream.ReadBuffer(BitsMem^, ImageSize);

HdcMem := CreateCompatibleDC( Handle ) ;
for i := 0 to 3000 do
begin
HBit := CreateDIBitmap(hdcMem,BitmapInfo^.bmiHeader,CBM_INIT,BitsMem,BitmapInfo^,DIB_RGB_COLORS);
SelectObject(hdcMem,HBit );

BitBlt(Handle,
0,0,BitmapInfo^.bmiHeader.biWidth,BitmapInfo^.bmiHeader.biHeight,
hdcMem,0,0,SrcCopy );
Image1.Canvas.TextOut(10,10,inttostr(i));
image1.Refresh ;
end;


finally
FreeMem(BitsMem);

Stream.Free ;
end;


end;

procedure TViewMain.Button3Click(Sender: TObject);
var
start : DWORD ;
i : Integer ;
begin
start := GetTickCount ;
DirectDisplay2('e:/1.bmp',image1.Canvas.Handle);
Caption := IntToStr(GetTickCount - start) ;
end;

procedure TViewMain.Button4Click(Sender: TObject);
var
start : DWORD ;
i : Integer ;
begin
start := GetTickCount ;
DirectDisplay3('e:/1.bmp',image1.Canvas.Handle);
Caption := IntToStr(GetTickCount - start) ;
end;

procedure TViewMain.DirectDisplay3(BmpFile: String; Handle: HDC);
var
Bmf: TBitmapFileHeader;
BitmapInfo: PBitmapInfo;
HeaderSize: Integer;
ImageSize: LongWord;
BitsMem: Pointer;
Stream: TFileStream;

hdd :THandle;
i : Integer ;
begin
try
Stream := TFileStream.Create(BmpFile, fmOpenRead or fmShareDenyWrite);
Stream.ReadBuffer(Bmf, sizeof(Bmf)); //&amp;para;&amp;Aacute;&amp;Icirc;&amp;Auml;&amp;frac14;&amp;thorn;&amp;Iacute;·
ImageSize := Stream.Size - sizeof(Bmf) ;
Stream.ReadBuffer(HeaderSize, sizeof(HeaderSize));

GetMem(BitmapInfo, HeaderSize + 12 + 256 * sizeof(TRGBQuad));
Stream.ReadBuffer(Pointer(Longint(BitmapInfo) + sizeof(HeaderSize))^,
HeaderSize - sizeof(HeaderSize)); //&amp;para;&amp;Aacute;&amp;Icirc;&amp;raquo;&amp;Iacute;&amp;frac14;&amp;ETH;&amp;Aring;&amp;Iuml;&amp;cent;
BitmapInfo^.bmiHeader.biSize := HeaderSize ;

Dec(ImageSize, HeaderSize);
GetMem(BitsMem,ImageSize);
Stream.ReadBuffer(BitsMem^, ImageSize);

hdd := DrawDibOpen; //&amp;acute;ò&amp;iquest;&amp;ordf;Draw&amp;frac34;&amp;auml;±ú

for i := 0 to 3000 do
begin
DrawDibDraw( hdd,Handle,
0, //&amp;Ocirc;&amp;shy;&amp;Iacute;&amp;frac14;&amp;Iuml;&amp;ntilde;
0,
BitmapInfo^.bmiHeader.biWidth*2,
BitmapInfo^.bmiHeader.biHeight*2,
BitmapInfo^.bmiHeader, //&amp;Ocirc;&amp;shy;&amp;Iacute;&amp;frac14;&amp;Iuml;&amp;ntilde;&amp;Iacute;·&amp;ETH;&amp;Aring;&amp;Iuml;&amp;cent;&amp;frac12;á&amp;sup1;&amp;sup1;
BitsMem, //&amp;Ocirc;&amp;shy;&amp;Iacute;&amp;frac14;&amp;Iuml;&amp;ntilde;&amp;Ecirc;&amp;yacute;&amp;frac34;&amp;Yacute;
0, //&amp;Iuml;&amp;Ocirc;&amp;Ecirc;&amp;frac34;
0,
BitmapInfo^.bmiHeader.biWidth,
BitmapInfo^.bmiHeader.biHeight,
DDF_SAME_HDC); //±ê&amp;Ouml;&amp;frac34;
Image1.Canvas.TextOut(10,10,inttostr(i));
//image1.Refresh;

end;


finally
DrawDibClose(hdd);
FreeMem(BitsMem);
Stream.Free ;
end;

end;

end.

在我的笔记中,还有一个VFW的函数,我测下来效率与我给你的函数差不多。其实用这个函数还有一个原因,XVID解压出来的视频正好是这个函数的参数,我在开发机器上,测下来1秒钟解压带显示能跑到1500帧,呵呵,能满足要求了。当然机器也比较好。用VC2005编译的。到这里只能祝你好运了。
 
to 张辉明
太感谢了!马上结贴!
 
多人接受答案了。
 
后退
顶部