目前有的程序是,当SockServer向SockClient发送控制消息时,SockServer先是将本地应用程序框大小发送到远程,SockClient将其当前显卡图像捕获,通过StretchBlt()将显卡图转化为与SockServer窗口大小一致的位图,并放入内存,用GlobalSize()确定一张图的大小。接着通过一个循环,将比特流(在循环设定的步长中整图被分成小块)不断存入由一个指针指向的一个缓存块中,由套接字传送出去,控制端以相同的手法,即用一个循环将这些比特流接入一个指定的内存块中,再由本地函数实现绘制。连接的频率由套接字的发送频率控制。但是抓出来的远程桌面质量很差,而且反应很慢。我觉得主要是压缩的问题,是不是可以先将BITMAP压成JPG格式的再传。不知道有没有高手有这方面的代码,即是在客户端抓屏后将图像压缩传输的实现代码。代码希望是VC平台下用API实现的。

解决方案 »

  1.   

    #include   <Stdio.h>   
      #include   <Objbase.h>   
      #include   <Windows.h>   
      #include   <Gdiplus.h>   
      #include   <GdiPlusEnums.h>   
      using   namespace   Gdiplus;   
      #pragma   comment(lib,"gdiplus")   
      //   Helper   functions   
      int   GetCodecClsid(const   WCHAR*,   CLSID*);   
        
      int   main()   
      {   
            CLSID                             codecClsid;   
            EncoderParameters     encoderParameters;   
            long                               quality;   
            Status                           stat;   
        
            //   Get   an   image   from   the   disk.   
            Image   image(L"Shapes.bmp");   
        
            //   Get   the   CLSID   of   the   JPEG   codec.   
            GetCodecClsid(L"image/jpeg",   &codecClsid);   
        
            //   Before   we   call   Image::Save,   we   must   initialize   an   
            //   EncoderParameters   object.   The   EncoderParameters   object   
            //   has   an   array   of   EncoderParameter   objects.   In   this   
            //   case,   there   is   only   one   EncoderParameter   object   in   the   array.   
            //   The   one   EncoderParameter   object   has   an   array   of   values.   
            //   In   this   case,   there   is   only   one   value   (of   type   LONG)   
            //   in   the   array.   We   will   set   this   value   to   0,   50,   and   100.   
        
            encoderParameters.Count   =   1;   
            encoderParameters.Parameter[0].Guid   =   EncoderQuality;   
            encoderParameters.Parameter[0].Type   =   EncoderParameterValueTypeLong;   
            encoderParameters.Parameter[0].NumberOfValues   =   1;   
        
            //   Save   the   image   as   a   JPEG   with   quality   level   0.   
            quality   =   0;   
            encoderParameters.Parameter[0].Value   =   &quality;   
            stat   =   image.Save(L"Shapes001.jpg",   &codecClsid,   &encoderParameters);   
        
            if(stat   ==   Ok)   
                  wprintf(L"%s   saved   successfully.\n",   L"Shapes001.jpg");   
            else   
                  wprintf(L"%d     Attempt   to   save   %s   failed.\n",   stat,   L"Shapes001.jpg");   
        
            //   Save   the   image   as   a   JPEG   with   quality   level   50.   
            quality   =   50;   
            encoderParameters.Parameter[0].Value   =   &quality;   
            stat   =   image.Save(L"Shapes050.jpg",   &codecClsid,   &encoderParameters);   
        
            if(stat   ==   Ok)   
                  wprintf(L"%s   saved   successfully.\n",   L"Shapes050.jpg");   
            else   
                  wprintf(L"%d     Attempt   to   save   %s   failed.\n",   stat,   L"Shapes050.jpg");   
        
            //   Save   the   image   as   a   JPEG   with   quality   level   100.   
            quality   =   100;   
            encoderParameters.Parameter[0].Value   =   &quality;   
            stat   =   image.Save(L"Shapes100.jpg",   &codecClsid,   &encoderParameters);   
        
            if(stat   ==   Ok)   
                  wprintf(L"%s   saved   successfully.\n",   L"Shapes100.jpg");   
            else   
                  wprintf(L"%d     Attempt   to   save   %s   failed.\n",   stat,   L"Shapes100.jpg");   
        
            return   0;   
      }   //   main   
      int   GetCodecClsid(const   WCHAR*   format,   CLSID*   pClsid)   
      {   
            UINT     num   =   0;                     //   number   of   image   encoders   
            UINT     size   =   0;                   //   size   of   the   image   encoder   array   in   bytes   
        
            ImageCodecInfo*   pImageCodecInfo   =   NULL;   
        
            GetImageEncodersSize(&num,   &size);   
            if(size   ==   0)   
                  return   -1;     //   Failure   
        
            pImageCodecInfo   =   (ImageCodecInfo*)(malloc(size));   
            if(pImageCodecInfo   ==   NULL)   
                  return   -1;     //   Failure   
        
            GetImageEncoders(num,   size,   pImageCodecInfo);   
        
            for(int   j   =   0;   j   <   num;   ++j)   
            {   
                  if(   wcscmp(pImageCodecInfo[j].MimeType,   format)   ==   0   )   
                  {   
                        *pClsid   =   pImageCodecInfo[j].Clsid;   
                        return   j;     //   Success   
                  }           
            }   //   for   
        
            return   -1;     //   Failure   
        
      }   //   GetCodecClsid
      

  2.   

    VNC的抓图方法还不太清楚,有代码但看不懂,有没有这方面的分析或者解释?
      

  3.   

    gdi+  可以直接将生成的HBITMAP 图转化为jpg,MSDN上有例子的,
      

  4.   

    有这样的方法么?GDI下我只会绘图。