如何将显示器上某个指定区域的内容抓成BMP图像文件?

解决方案 »

  1.   

    可以下个抓屏软件,如HyperCam,可以是图片也可是动态的。
      

  2.   

    procedure TForm1.FormClick(Sender: TObject);
    var winHWND, hCur:integer; 
         winDC:integer;
         rect:TRect;
         //AFormat : Word;
         //AData,APalette : THandle;
         pt:TPoint;
         fBitmap:TBitmap;
    begin
         hCur := GetCursor(); // 获 得 光 标 句 柄 
         GetCursorPos(pt); // 记 录 光 标 位 置 
         winHWND := GetDesktopWindow(); 
         winDC := GetDC(winHWND); 
         GetWindowRect(winHWND, rect); 
         fBitmap := TBitmap.create; 
         fBitmap.width := rect.right-rect.left; 
         fBitmap.height := rect.bottom-rect.top; 
         BitBlt(fBitmap.canvas.handle, 0, 0, fBitmap.width, fBitmap.height, winDC, 0, 0, SRCCOPY); 
         DrawIcon(fBitmap.canvas.handle, pt.x, pt.y, hCur); // 画 光 标 
         ReleaseDC(winHWND, winDC); 
         Image1.Picture.Bitmap.Assign(fBitmap);
         fBitmap.Free;
    end;
      

  3.   

    var
      hScr :long;
      bmp  :TBitmap;
      sw,sh,sl,st,w,h:integer;
    begin
      sl := 0;
      st := 0;
      sw := 100;
      sh := 100;
      w  := 200;
      h  := 200;
      hScr := CreateDC("DISPLAY",0,0,0);
      if(hScr<>0)
        begin
          bmp := TBitmap.Create();
          bmp.Width:=w;
          bmp.Height:=h;
          StretchBlt(bmp.Canvas.Handle,0,0,w,h,hScr,sl,st,sw,sh,SRCCOPY);
          DeleteDC(hScr);
          bmp.SaveToFile('my.bmp');
          bmp.Destroy();
        end
    end
      

  4.   

    BCB写的代码,可以抓整屏、自己由鼠标选区域抓取。
    #ifndef untCaptureH
    #define untCaptureH#include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <Dialogs.hpp>
    #include <ExtCtrls.hpp>
    #include <Menus.hpp>class TForm1 : public TForm
    {
    __published: // IDE-managed Components
        TScrollBox *ScrollBox1;
        TMainMenu *MainMenu1;
        TSaveDialog *SaveDialog1;
        TImage *Image1;
        TMenuItem *File1;
        TMenuItem *Save1;
        TMenuItem *Exit1;
        TMenuItem *Action1;
        TMenuItem *N1;
        TMenuItem *N2;
        TMenuItem *N3;
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall FormDestroy(TObject *Sender);
        void __fastcall Save1Click(TObject *Sender);
        void __fastcall N1Click(TObject *Sender);
        void __fastcall N2Click(TObject *Sender);
        void __fastcall N3Click(TObject *Sender);
        void __fastcall Exit1Click(TObject *Sender);
        void __fastcall CaptureDesktop(HDC DesImage);
        HWND __fastcall GetTopWndHandle(void);
        void __fastcall CaptureWndImage(TRect rect);
    private: // User declarations
    public: // User declarations
        __fastcall TForm1(TComponent* Owner);
    };extern PACKAGE TForm1 *Form1;
    #endif
    ////实现代码///////////
    #include <vcl.h>
    #include <math.h>
    #pragma hdrstop#include "untCapture.h"
    #include "untShow.h"#pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    Graphics::TBitmap *KABitmap;//捕获整个窗口
    void __fastcall TForm1::CaptureDesktop(HDC DesImage)
    {
        HDC hdc = GetDC(0);
        BitBlt(DesImage,0,0,Screen->Width,Screen->Height,hdc,0,0,SRCCOPY);
        ReleaseDC(0,hdc);
    }//捕获活动窗口
    HWND __fastcall TForm1::GetTopWndHandle(void)
    {
        HWND hwnd = GetTopWindow(0);
        while(hwnd != 0)
        {
            if(IsWindowVisible(hwnd) && (GetWindowLong(hwnd,GWL_EXSTYLE) & WS_EX_TOPMOST) == 0)
            {
                if(IsIconic(hwnd))
                    hwnd = GetDesktopWindow();
                return hwnd;
            }
            hwnd = GetNextWindow(hwnd,GW_HWNDNEXT);
        }
        return 0;
    }void __fastcall TForm1::CaptureWndImage(TRect rect)
    {
        // First set the size of the Bitmap.
        KABitmap->Width = rect.Right - rect.Left;
        KABitmap->Height = rect.Bottom - rect.Top;
        // Get the seleted part of the Desktop Image
        //    ScreenDC = GetDC( 0 );
        HDC  ScreenDC= GetDC(0);
        try
        {
            StretchBlt(KABitmap->Canvas->Handle, 0, 0,
                     KABitmap->Width, KABitmap->Height, ScreenDC,
                     rect.Left, rect.Top,
                     KABitmap->Width,
                     KABitmap->Height,
                     SRCCOPY);
        }
        __finally
        {
            ReleaseDC(0, ScreenDC);
        }
    }__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    }void __fastcall TForm1::FormCreate(TObject *Sender)
    {
        KABitmap = new Graphics::TBitmap();
    }void __fastcall TForm1::FormDestroy(TObject *Sender)
    {
        KABitmap->Free();
    }void __fastcall TForm1::Save1Click(TObject *Sender)
    {
        int i=1;
        SaveDialog1->FileName = "Captured1.bmp";
        while (FileExists(SaveDialog1->FileName))
        {
          i++;
          SaveDialog1->FileName = "Captured"+IntToStr(i)+".bmp";
        }
        if(SaveDialog1->Execute())
        {
          Image1->Picture->SaveToFile(SaveDialog1->FileName);
        }
    }void __fastcall TForm1::N1Click(TObject *Sender)
    {
        Form1->Visible=false;
        // Initializations
        Image1->Width=Screen->Width;
        Image1->Height=Screen->Height;    // Give the Display time to refresh
        Sleep(2000);    // Copy the Desktop to Image1
        CaptureDesktop(Image1->Canvas->Handle);    // Show Form1
        Form1->Visible=true;
    }void __fastcall TForm1::N2Click(TObject *Sender)
    {
        TRect rect;
        Application->Minimize();
        // Give some time to refresh and to use to select a window
        Sleep(3000);
        // Get the handle of the top active window
        HWND WinHandle =GetTopWndHandle();
        // Get the size of this window
        GetWindowRect(WinHandle, &rect);
        // Put the Image of the top active window in the KABitmap
        CaptureWndImage(rect);
        // Now Copy the KABitmao to Image1
        Image1->Width = KABitmap->Width;
        Image1->Height = KABitmap->Height;
        Image1->Picture->Bitmap = KABitmap;
        Application->Restore();
    }void __fastcall TForm1::N3Click(TObject *Sender)
    {
        Form1->Visible=false;
        // Initializations
        Image1->Width=Screen->Width;
        Image1->Height=Screen->Height;
        Form2->Origin.x = Form2->MovePt.x =0;
        Form2->Origin.y = Form2->MovePt.y =0;
        Form2->IsRegionSelected=false;    // Give the Display time to refresh
        Sleep(500);    // Copy the Desktop Image to Form2 Image
        CaptureDesktop(Form2->Image1->Canvas->Handle);
        // Show Form2
        Form2->Visible=true;
    }void __fastcall TForm1::Exit1Click(TObject *Sender)
    {
        Application->Terminate();
    }
      

  5.   

    还有一个使用Delphi写的,只支持抓取某窗体(或窗体控件)的区域。
    {***************************************************************
     * 方 法 名  : g_fun_SnatchScreen
     * 编写目的   : 拷屏
     * 作    者  : 黄仁光
     * 参    数  : HWnd:THandle
     * 结    果  : None
     * 编写日期   :2002年12月31日
     ****************************************************************}
    procedure g_fun_SnatchScreen(HWnd:THandle);
    var
      TheRECT: TRect;
      TheWidth: integer;
      TheHeight: integer;
      SourceDC: integer;
      DestDC: integer;
      BHandle: integer;
      Wnd: integer;
    begin
      GetWindowRect(HWnd, therect);
      thewidth := therect.Right - therect.left;
      TheHeight := therect.Bottom - therect.Top;
      sourcedc := CreateDC('Display', 0, 0, 0);
      DestDC := CreateCompatibleDC(sourcedc);
      BHandle := CreateCompatibleBitmap(sourcedc, thewidth, TheHeight);
      SelectObject(DestDC, BHandle);
      BitBlt(DestDC, 0, 0, TheWidth, TheHeight, SourceDC, TheRECT.Left, TheRECT.Top, MERGECOPY);
      wnd := HWnd;
      OpenClipboard(Wnd);
      EmptyClipboard;
      SetClipboardData(2, BHandle);
      CloseClipboard;
      DeleteDC(DestDC);
      ReleaseDC(BHandle, SourceDC);
    end;
      

  6.   

    会有损失吗?抓屏不过是通过GDI 复制窗体(桌面,可视控件都是窗体)内容的过程,这种方法会忠实的纪录每一个像素,要说到像素丢失,只可能在用GDI StretchBlt进行图像放缩时发生,而上面的代码只有 halibut 的用了,用BitBlt是无法放缩图像的,也就不可能丢失像素!其实在Delphi中,TCanvas类已经封装了这些,将HDC传递给一个Canvas实例,即可直接操作,如
    Canvas.Handle:=GetDC(0);对应BitBlt,StretchBlt分别有Canvas.Draw,Canvas.StretchD
      

  7.   

    var
      hScr :long;
      bmp  :TBitmap;
      sw,sh,sl,st,w,h:integer;
    begin
      sl := 0;
      st := 0;
      sw := 100;
      sh := 100;
      w  := 200;
      h  := 200;
      hScr := CreateDC("DISPLAY",0,0,0);
      if(hScr<>0)
        begin
          bmp := TBitmap.Create();
          bmp.Width:=w;
          bmp.Height:=h;
          StretchBlt(bmp.Canvas.Handle,0,0,w,h,hScr,sl,st,sw,sh,SRCCOPY);
          DeleteDC(hScr);
          bmp.SaveToFile('my.bmp');
          bmp.Destroy();
        end
    end