用什么方法可以截取屏幕上指定区域的位图?

解决方案 »

  1.   

    获得屏幕DC,然后BitBlt。仔细看BitBlt的参数就知道了。
      

  2.   

    HBITMAP CopyDCToBitmap(HDC hScrDC, LPRECT lpRect)
    {
    HDC        hMemDC; // 屏幕和内存设备描述表    
    HBITMAP    hBitmap,hOldBitmap;  // 位图句柄
    int       nX, nY, nX2, nY2;     // 选定区域坐标
    int       nWidth, nHeight;      // 位图宽度和高度 if (IsRectEmpty(lpRect)) // 确保选定区域不为空矩形
    return NULL;

    // 获得选定区域坐标
    nX = lpRect->left;
    nY = lpRect->top;
    nX2 = lpRect->right;
    nY2 = lpRect->bottom;
    nWidth = nX2 - nX;
    nHeight = nY2 - nY;

    hMemDC = CreateCompatibleDC(hScrDC);//为屏幕设备描述表创建兼容的内存设备描述表

    // 创建一个与屏幕设备描述表兼容的位图
    float factor = 1.0f;
    hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
    while(!hBitmap)
    {
    factor -= 0.05f;
    hBitmap = CreateCompatibleBitmap(hScrDC, (int)(nWidth*factor), (int)(nHeight*factor));
    }
    // 把新位图选到内存设备描述表中
    hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
    // 把屏幕设备描述表拷贝到内存设备描述表中
    StretchBlt(hMemDC,0,0,nWidth,nHeight,hScrDC,nX,nY,nWidth,nHeight,SRCCOPY);
    //BitBlt(hMemDC, 0, 0, nWidth, nHeight,hScrDC, nX, nY, SRCCOPY);
    //得到屏幕位图的句柄  hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
    //清除 

    // DeleteDC(hScrDC);
    DeleteDC(hMemDC);
    DeleteObject(hOldBitmap);
    // 返回位图句柄
    return hBitmap;
    }
      

  3.   

    这些方法都是copy特定窗口位图。我想要拷贝屏幕上任意指定区域的位图,其实就是屏幕抓图。
      

  4.   

    这是一个保存整个屏幕的,你可以改为保存一部分,代码是BCB下的:
    Ddraw.cpp从SDK里找去
    先要:    //初始化DirectDraw环境,并实现DirectDraw功能
        InitDDraw(lpDD,lpDDSPrimary)
    最后要:
    FreeDDraw(lpDD,lpDDSPrimary);保存的CPP
    bool Is555=true;
    inline unsigned char GetRed(WORD color)
    {
    if( Is555 )
    return (color>>7) & 0xff;
    else
    return (color>>8) & 0xff;
    }inline unsigned char GetGreen(WORD color)
    {
    if( Is555 )
    return (color>>2) & 0xff;
    else
    return (color>>3) & 0xff;
    }
    inline unsigned char GetBlue(WORD color)
    {
    return (color & 0x1f) << 3;
    }
    bool SaveToBitmapFile(LPDIRECTDRAWSURFACE lpSurface, char* filename)
    {
    WORD* lpBuffer; // 表面指针
    int nPitch;  // 表面跨距
    int nWidth, nHeight; // 表面宽高///////////////
    /////////////        HWND hwnd=GetActiveWindow();
    // 打开文件s
    FILE* fp;
    if( (fp=fopen(filename, "wb")) != NULL )
    {
    // 锁定表面
    DDSURFACEDESC ddsd;
    ddsd.dwSize = sizeof(ddsd);
                    ShowWindow(hwnd,SW_MINIMIZE);
    HRESULT ddrval = lpSurface->Lock( NULL, &ddsd, DDLOCK_WAIT, NULL );
    //                ddsd.lPitch//每行数据总字节数
    //                ShowMessage("RM:"+AnsiString(ddsd.ddpfPixelFormat.dwRBitMask)+
    //                        "GM:"+AnsiString(ddsd.ddpfPixelFormat.dwGBitMask)
    //                        +"BM:"+AnsiString(ddsd.ddpfPixelFormat.dwBBitMask)
    //                        +"lPitch:"+AnsiString(ddsd.lPitch));
    if( ddrval == DD_OK )
    {
       lpBuffer = (WORD *)ddsd.lpSurface;
    nWidth = ddsd.dwWidth;
    nHeight = ddsd.dwHeight;
    nPitch  = ddsd.lPitch >> 1; //lPitch以Byte为单位,GraphPitch以WORD为单位。所以GraphPitch = lPitch / 2;
                            if(ddsd.ddpfPixelFormat.dwBBitMask==31)Is555=false;
    } // 保存文件头
                    fputc(0x42,fp);
                    fputc(0x4d,fp);
                    fputc( (nWidth * nHeight * 3 + 0x36)&0xff,fp);
                    fputc(((nWidth * nHeight * 3 + 0x36)>>8)&0xff,fp);
                    fputc(((nWidth * nHeight * 3 + 0x36)>>16)&0xff,fp);
                    fputc(((nWidth * nHeight * 3 + 0x36)>>24)&0xff,fp);
                    fputc(0,fp);fputc(0,fp);
                    fputc(0,fp);fputc(0,fp);
                    fputc(0x36,fp);
                    fputc(0,fp);fputc(0,fp);fputc(0,fp); // 保存文件信息
    BITMAPINFOHEADER Header;
    Header.biSize = sizeof(BITMAPINFOHEADER);// 结构的大小
    Header.biWidth = nWidth;  // 宽
    Header.biHeight = nHeight;// 高
    Header.biPlanes = 1;   // 固定
    Header.biBitCount = 24;   // 颜色数
    Header.biCompression = BI_RGB; // 是否压缩
    Header.biSizeImage = nWidth * nHeight * 3;// 图片的大小
    Header.biXPelsPerMeter = 0;
    Header.biYPelsPerMeter = 0;
    Header.biClrUsed = 0;
    Header.biClrImportant = 0;
    fwrite(&Header, Header.biSize, 1, fp);
    // 写入具体内容(从下向上存放)
    fseek(fp, 0x36, SEEK_SET);
                switch(ddsd.ddpfPixelFormat.dwRGBBitCount)
                {
                   case 8:
                     {
                          BYTE *tem=(BYTE *)ddsd.lpSurface;
                          PALETTEENTRY entry[256];
                          HDC hScrDC=CreateDC("DISPLAY",NULL,NULL,NULL);
                          ::GetSystemPaletteEntries(hScrDC,0,256,entry);
                              for(int y=(int)nHeight-1;y>=0;y--)
                              {
                                 for(int x=0;x<(int)nWidth;x++)
                                 {
                                     fputc(entry[tem[x+ddsd.lPitch*y]].peBlue,fp);
                                     fputc(entry[tem[x+ddsd.lPitch*y]].peGreen,fp);
                                     fputc(entry[tem[x+ddsd.lPitch*y]].peRed,fp);
                                 }
                              }
                          DeleteDC(hScrDC);
                              break;
                     }
                   case 16:
             { WORD word;
             lpBuffer += nWidth * (nHeight - 1);
             for(int i=0; i<nHeight; i++)
            {
             for(int j=0; j<nWidth; j++)
             {
             word = *lpBuffer;
             fputc( GetBlue( word ), fp); // 蓝
            fputc( GetGreen( word ), fp); // 绿
             fputc( GetRed( word ), fp);     // 红         lpBuffer++;
             }
             lpBuffer -= nPitch*2; // 指针转到上一行的开始
             }
                            break;
                      }
                   case 24:
    //               case 32:
                      {
                          BYTE *tem=(BYTE *)ddsd.lpSurface;
                          tem+=nWidth * (nHeight - 1)*3;
    //                      ShowMessage(AnsiString(ddsd.lPitch));
                          for(int y=(int)nHeight-1;y>=0;y--)
                              {
                                 for(int x=0;x<(int)nWidth;x++)
                                 {
                                     fputc(*tem++,fp);
                                     fputc(*tem++,fp);
                                     fputc(*tem++,fp);
                                 }
                                 tem-=ddsd.lPitch*2;
                              }
                              break;
                      }
                    case 32:
                      {
                          BYTE *tem=(BYTE *)ddsd.lpSurface;
                          tem+=nWidth * (nHeight - 1)*4;
    //                      ShowMessage(AnsiString(ddsd.lPitch));
                          for(int y=(int)nHeight-1;y>=0;y--)
                              {
                                 for(int x=0;x<(int)nWidth;x++)
                                 {                                 fputc(*tem++,fp);
                                     fputc(*tem++,fp);
                                     fputc(*tem++,fp);
                                     tem++;
                                  }
                                 tem-=ddsd.lPitch*2;
                              }
                              break;
                      }
                 }//end switch fclose(fp); // 解锁表面
    ddrval = lpSurface->Unlock( NULL );
                    PostMessage(hwnd,WM_QUIT,0,0);
    return true;
    } return false;
    }