我在客户端截取屏幕之后,取得是DDB位图,是否需要转换成DIB位图,才能发到服务器?服务器端收到DIB位图之后,是不是可以直接显示DIB位图,要不要转换成DDB格式?

解决方案 »

  1.   

    如果能正常收到的话,就可以直接显示DIB
      

  2.   

    是啊,在转化为DIB的时候压缩的,是压缩的DIB。
      

  3.   

    一般采用先jpg压缩,再传输,解压,显示
      

  4.   

    #define MAXXCount 10 //屏幕X方向最多分割块数
    #define MAXYCount 5 //... Y................
    #define DestNum 1000 //每块的偏移检测点最大个数
    COLORREF Colors[MAXXCount][MAXYCount][DestNum];
    COLORREF BakColors[MAXXCount]{MAXYCount][DestNum];
    TPoint Dests[DestNum];
    int Sw;
    int Sh;
    int xCount;
    int yCount;
    int ItemWidth;
    int ItemHeight;
    int Dnum;
    int Qlity;
    //得到消息后执行:
    //另外:接收到的数据包中分析出 Dnum ,Qlity
    //Dnum:偏移观测点数量
    //Qlity:图象要求质量
    __fastcall TForm1::CopyScreen(int DNum,int Qlity){
    ItemWidth=Sw/xCount;
    ItemHeight=Sh/yCount;
    Sw=Screen->Width;
    Sh=Screen->Height;
    xCount=(Sw>1000)?8:6;
    yCount=(Sh>1000)?3:2;
    for (int num1=0;num1 Dests[num1].x=random(ItemWidth);
    Dests[num1].y=random(ItemHeight);
    }
    CatchScreen(DNum,Qlity);
    }
    //收到刷屏消息后只执行:
    CatchScreen(DNum,Qlity);
    __fastcall TForm1::CatchScreen(int DNum,int Qlity){
    //函数功能:扫描改变的屏幕区域,并切经过优化处理,最后发送这些区域数据
    //DNum: 偏移量 Qlity:图象质量
    HDC dc=GetDC(GetDesktopWindow());
    Graphics::TBitmap *bm=new Graphics::TBitmap;
    bm->Width=Sw;
    bm->Height=Sh;
    BitBlt(bm->Canvas->Handle,0,0,Sw-1,Sh-1,dc,0,0);
    int num1,num2,num3;
    int nowx,nowy;
    bool Change;
    bool ItemChange[MAXXCount][MAXYCount];
    for (num1=0;num1 nowx=ItemWidth*num1;
    for (num2=0;num2 nowy=ItemHeight*num2;
    Change=false;
    for (num3=0;num3 Colors[num1][num2][num3]=bm->Canvas->Pixels[nowx+Dests[num3].x][nowy+Dests[num3].y];
    if (Colors[num1][num2][num3]!=BakColors[num1][num2][num3]){
    BakColors[num1][num2][num3]=Colors[num1][num2][num3];
    ItemChange[num1][num2]=true;
    }
    }
    }
    }
    int CNum,MaxCNum;
    int ChangedNum=0;
    TRect *Rect;
    int num4;
    int MinSize=10000;
    int m;
    TRect MinRect;
    Graphics::TBitmap *bt2=new Graphics::TBitmap;
    TJPEGImage *j=new TJPEGImage;
    //************************
    j->Quality=Qlity;
    //************************
    CopyScreenUint CopyScreen;
    CopyScreenItemUint CopyScreenItem;
    TMemoryStream *ms=new TMemoryStream;
    ms->Write(&TcpMsg,sizeof(TcpMsgUint));
    ms->Write(&CopyScreen,sizeof(CopyScreenUint));
    do{
    for (num1=0;num1 for (num2=0;num2 for (num3=num1+1;num3<=xCount;num3++){
    MaxCNum=0;
    for (num4=num2+1;num4<=yCount;num4++){ //遍历所有矩形
    CNum=GetChangedNum(TRect(num1,num2,num3,num4));
    if (CNum>MaxCNum) MaxCNum=CNum;
    m=(num3-num1)*(num4-num2);
    if (2*m-CNum MinSize=2*m-CNum;
    MinRect=TRect(num1,num2,num3,num4);
    }
    }
    }
    TMemoryStream *ms;
    BitBlt(bt2->Canvas->Handle,0,0,ItemWidth-1,ItemHeight-1,bt->Canvas->Handle,0,0);
    j->Assign(bt2);
    j->SaveToStream(ms2);
    CopyScreenItem.Rect=TRect(num1,num2,num3,num4);
    CopyScreenItem.FileType=JPEGFILE; //JPEGFILE 定义为:#define JPEGFILE 1
    ms2->Position=0;
    CopyScreenItem.Length=ms2->Size;
    ms->Write(&CopyScreenItem,sizeof(ScreenItemUint));
    ms->CopyFrom(ms2,ms2->Size);
    ChangedNum++;
    }while(MaxCNum>0);
    TcpMsg.Type=MsgCopyScreen;
    ms->Position=0;
    TcpMsg.Length=ms->Size-sizeof(TcpMsgUint);
    CopyScreen.Count=ChangedNum;
    ms->Write(&TcpMsg,sizeof(TcpMsgUint));
    ms->Write(&CopyScreen,sizeof(CopyScreenUInt));
    ms->Position=0;
    sock->SendStream(ms);
    }  这个程序把屏幕画面切分为了多个部分,并存储画面为JPG格式,这样压缩率就变的十分的高了。通过这种方法压缩处理过的数据,变得十分小,甚至在屏幕没有改变的情况下,传送的数据量为0,你可以仔细看看
      

  5.   

    //图形转换
    HANDLE DDBtoDIB( HBITMAP bitmap) 
    {
    BITMAP bm;
    BITMAPINFOHEADER bi;
        LPBITMAPINFOHEADER  lpbi;
    DWORD dwLen;
    HANDLE hDib;
    HANDLE handle;
    HDC  hdc;
    HPALETTE hPal; hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE ); //获得位图信息
    GetObject(bitmap,sizeof(bm),(LPSTR)&bm); // 初始化位图头信息
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bm.bmWidth;
    bi.biHeight  = bm.bmHeight;
    bi.biPlanes  = 1; bi.biBitCount = 4;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0; int ncolors = (1 << bi.biBitCount); 
    if( ncolors> 256 ) 
    ncolors = 0;
    dwLen  = bi.biSize + ncolors * sizeof(RGBQUAD); hdc = GetDC(NULL);
    hPal = SelectPalette(hdc,hPal,FALSE);
    RealizePalette(hdc); hDib = GlobalAlloc(GMEM_FIXED,dwLen); if (!hDib){
    SelectPalette(hdc,hPal,FALSE);
    ReleaseDC(NULL,hdc);
    return NULL;
    } lpbi = (LPBITMAPINFOHEADER)hDib; *lpbi = bi; GetDIBits(hdc, bitmap, 0L, (DWORD)bi.biHeight,
    (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS ); bi = *lpbi; if (bi.biSizeImage == 0)
    {
    bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) 
    * bi.biHeight;
    } dwLen += bi.biSizeImage;
    if (handle = GlobalReAlloc(hDib, dwLen, GMEM_MOVEABLE))
    hDib = handle;
    else
    {
    GlobalFree(hDib); SelectPalette(hdc,hPal,FALSE);
    ReleaseDC(NULL,hdc);
    return NULL;
    } lpbi = (LPBITMAPINFOHEADER)hDib; BOOL bgotbits = GetDIBits( hdc, bitmap,
    0L,
    (DWORD)bi.biHeight,
    (LPBYTE)lpbi 
    + (bi.biSize + ncolors * sizeof(RGBQUAD)),
    (LPBITMAPINFO)lpbi,
    (DWORD)DIB_RGB_COLORS); if( !bgotbits )
    {
    GlobalFree(hDib);

    SelectPalette(hdc,hPal,FALSE);
    ReleaseDC(NULL,hdc);
    return NULL;
    } SelectPalette(hdc,hPal,FALSE);
    ReleaseDC(NULL,hdc); return hDib;
    }
      

  6.   

    //获得桌面图形
    HBITMAP GetSrcBit(DWORD BitWidth,DWORD BitHeight)
    {
    HDC hdcmy,hbufferdc;
    HBITMAP  hBit,hOldBitmap; hdcmy = CreateDC("DISPLAY",NULL,NULL,NULL);
    hbufferdc = CreateCompatibleDC(hdcmy); hBit = CreateCompatibleBitmap(hdcmy, BitWidth, BitHeight); hOldBitmap = (HBITMAP)SelectObject(hbufferdc, hBit);
    StretchBlt(hbufferdc, 0, 0, BitWidth, BitHeight,
    hdcmy, 0, 0,SysWidth,SysHeight, SRCCOPY); hBit = (HBITMAP)SelectObject(hbufferdc, hOldBitmap);

    DeleteObject(hOldBitmap);
    ReleaseDC(NULL,hdcmy);
    ReleaseDC(NULL,hbufferdc); return hBit;
    }//---------------------------------------------------------------
    //发送桌面屏幕
    void SendDesktop() 
    {
    int BitMsg;
    LPBYTE plmagePoint;
    HANDLE hDib;
    HBITMAP hBit;
    int BitHeight,BitWidth; //获得桌面宽度和高度
    recv(NewSock,(char*)&BitWidth,sizeof(BitWidth)+1,0);
    recv(NewSock,(char*)&BitHeight,sizeof(BitHeight)+1,0);
    if (BitWidth > SysWidth)
    BitWidth = SysWidth;
    if (BitHeight > SysHeight)
    BitHeight = SysHeight; //转换为位图形式
    hBit = GetSrcBit(BitWidth,BitHeight); hDib = DDBtoDIB(hBit);
    DWORD bitSize = GlobalSize(hDib);

    send(NewSock,(char*)&bitSize,sizeof(bitSize)+1,MSG_OOB);
    recv(NewSock,(char*)&BitMsg,sizeof(BitMsg)+1,0); plmagePoint = (LPBYTE)hDib;
    for(WORD i=0;i<bitSize/US_MAXSIZE;i++)
    {
    send(NewSock,(char*)plmagePoint,sizeof(BYTE)*US_MAXSIZE,MSG_OOB);
    plmagePoint = plmagePoint + US_MAXSIZE;
        recv(NewSock,(char*)&BitMsg,sizeof(BitMsg)+1,0);
    }
    if (bitSize%US_MAXSIZE)
    {
    send(NewSock,(char*)plmagePoint,sizeof(BYTE)*GlobalSize(hDib)%US_MAXSIZE,MSG_OOB);
        recv(NewSock,(char*)&BitMsg,sizeof(BitMsg)+1,0);
    } DeleteObject(hBit);
    GlobalFree(hDib);
    }