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

Description of your first forum.

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

帖子3cs » 星期三, 2008年6月4日 17:54


我用Stretchblt方法把一张320*240的BMP图片放大到800*600用了>100毫秒的时间,大家有没有好的算法把这个缩放的时间控制在<15毫秒以上呀?(我的本本是CPU1.2,内存是256)
 
 
 

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

帖子MyMidas » 星期三, 2008年6月4日 17:55


gdi+
 
 
 

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

帖子3cs » 星期三, 2008年6月4日 17:57


to:MyMidas
Gdi+不熟呀,能不能给点具体的算法![:)]
 
 
 

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

帖子MyMidas » 星期三, 2008年6月4日 18:27


dibdraw
 
 
 

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

帖子地质灾害 » 星期四, 2008年6月5日 08:22


升级下电脑就好了。[:D]
 
 
 

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

帖子fanboynet » 星期四, 2008年6月5日 09:03


DirectX...
 
 
 

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

帖子张辉明 » 星期四, 2008年6月5日 10:07


呵呵 是要显示视频吧,用 StretchDIBits吧。速度一流,
当然也可以用DX SHOW
 
 
 

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

帖子3cs » 星期四, 2008年6月5日 19:37


to 张辉明:
对,我是显示视频,能不能说说StretchDibits这个函数的用法吗?
 
 
 

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

帖子3cs » 星期四, 2008年6月5日 20:13


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方法更快的缩放算法,有的别藏着呀!

帖子3cs » 星期四, 2008年6月5日 20:58


我用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函数实现在的方法,谢谢!
 
 
 

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

帖子张辉明 » 星期四, 2008年6月5日 22:41


各种函数的性能测试。哈哈不仅教了你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;
    Time r1: 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[i] is TMenuItem then
        (Components[i] 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));       //&para;&Aacute;&Icirc;&Auml;&frac14;&thorn;&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));          //&para;&Aacute;&Icirc;&raquo;&Iacute;&frac14;&ETH;&Aring;&Iuml;&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));       //&para;&Aacute;&Icirc;&Auml;&frac14;&thorn;&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));          //&para;&Aacute;&Icirc;&raquo;&Iacute;&frac14;&ETH;&Aring;&Iuml;&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));       //&para;&Aacute;&Icirc;&Auml;&frac14;&thorn;&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));          //&para;&Aacute;&Icirc;&raquo;&Iacute;&frac14;&ETH;&Aring;&Iuml;&cent;
    BitmapInfo^.bmiHeader.biSize := HeaderSize ;

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

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

    for i := 0 to 3000 do
    begin
       DrawDibDraw( hdd,Handle,
                      0, //&Ocirc;&shy;&Iacute;&frac14;&Iuml;&ntilde;
                      0,
                      BitmapInfo^.bmiHeader.biWidth*2,
                      BitmapInfo^.bmiHeader.biHeight*2,
                      BitmapInfo^.bmiHeader, //&Ocirc;&shy;&Iacute;&frac14;&Iuml;&ntilde;&Iacute;·&ETH;&Aring;&Iuml;&cent;&frac12;á&sup1;&sup1;
                      BitsMem, //&Ocirc;&shy;&Iacute;&frac14;&Iuml;&ntilde;&Ecirc;&yacute;&frac34;&Yacute;
                      0, //&Iuml;&Ocirc;&Ecirc;&frac34;
                      0,
                      BitmapInfo^.bmiHeader.biWidth,
                      BitmapInfo^.bmiHeader.biHeight,
                      DDF_SAME_HDC); //±ê&Ouml;&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编译的。到这里只能祝你好运了。
 
 
 

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

帖子3cs » 星期四, 2008年6月5日 23:01


to 张辉明
太感谢了!马上结贴!
 
 
 

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

帖子3cs » 星期四, 2008年6月5日 23:02


多人接受答案了。