• <small id='TBWqq'></small><noframes id='TBWqq'>

  • <legend id='TBWqq'><style id='TBWqq'><dir id='TBWqq'><q id='TBWqq'></q></dir></style></legend>
      <bdo id='TBWqq'></bdo><ul id='TBWqq'></ul>

    <tfoot id='TBWqq'></tfoot>

    1. <i id='TBWqq'><tr id='TBWqq'><dt id='TBWqq'><q id='TBWqq'><span id='TBWqq'><b id='TBWqq'><form id='TBWqq'><ins id='TBWqq'></ins><ul id='TBWqq'></ul><sub id='TBWqq'></sub></form><legend id='TBWqq'></legend><bdo id='TBWqq'><pre id='TBWqq'><center id='TBWqq'></center></pre></bdo></b><th id='TBWqq'></th></span></q></dt></tr></i><div id='TBWqq'><tfoot id='TBWqq'></tfoot><dl id='TBWqq'><fieldset id='TBWqq'></fieldset></dl></div>

        C++ gdi::Bitmap to PNG Image in memory

        时间:2023-12-02
      1. <legend id='m9qKp'><style id='m9qKp'><dir id='m9qKp'><q id='m9qKp'></q></dir></style></legend><tfoot id='m9qKp'></tfoot>
      2. <small id='m9qKp'></small><noframes id='m9qKp'>

          <bdo id='m9qKp'></bdo><ul id='m9qKp'></ul>

            <i id='m9qKp'><tr id='m9qKp'><dt id='m9qKp'><q id='m9qKp'><span id='m9qKp'><b id='m9qKp'><form id='m9qKp'><ins id='m9qKp'></ins><ul id='m9qKp'></ul><sub id='m9qKp'></sub></form><legend id='m9qKp'></legend><bdo id='m9qKp'><pre id='m9qKp'><center id='m9qKp'></center></pre></bdo></b><th id='m9qKp'></th></span></q></dt></tr></i><div id='m9qKp'><tfoot id='m9qKp'></tfoot><dl id='m9qKp'><fieldset id='m9qKp'></fieldset></dl></div>
              <tbody id='m9qKp'></tbody>

                1. 本文介绍了C++ gdi::Bitmap to PNG Image in memory的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在尝试通过 tcp 将窗口的屏幕截图发送到服务器.获取屏幕截图没有问题(使用 GDIplus).网络对我来说也很容易.问题是试图将 gdi+ 位图转换为 png(在内存中)以从中获取数据并将其发送到服务器.有人可以帮我吗?

                  I'm trying to send a screenshot of a window over tcp to a server. Getting the screenshot is no problem (using GDIplus). The networking is also easy for me. The problem is trying to convert the gdi+ Bitmap to a png (in memory) to get the data out of it and send it to the server. Can anyone help me please?

                  推荐答案

                  Gdiplus 可以保存到文件,或者使用 IStream 保存到内存.请参阅 Gdiplus::Image::Save 方法

                  Gdiplus can save to file, or save to memory using IStream. See Gdiplus::Image::Save method

                  //get gdi+ bitmap
                  Gdiplus::Bitmap bitmap(hbitmap, nullptr);
                  
                  //write to IStream
                  IStream* istream = nullptr;
                  HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, &istream);
                  CLSID clsid_png;
                  CLSIDFromString(L"{557cf406-1a04-11d3-9a73-0000f81ef32e}", &clsid_png);
                  bitmap.Save(istream, &clsid_png);
                  

                  内存足够小,您可以从 IStream 复制到单个缓冲区:

                  The memory size is small enough that you can copy from IStream to a single buffer:

                  //copy IStream to buffer
                  int bufsize = GlobalSize(hg);
                  char *buffer = new char[bufsize];
                  
                  //lock & unlock memory
                  LPVOID ptr = GlobalLock(hg);
                  memcpy(buffer, ptr, bufsize);
                  GlobalUnlock(hg);
                  
                  //release will automatically free the memory allocated in CreateStreamOnHGlobal 
                  istream->Release();
                  

                  PNG 现在可以在 buffer 中使用,其大小为 bufsize.您可以直接处理二进制数据,也可以转换为 Base64 以通过网络发送

                  PNG is now available in buffer, its size is bufsize. You can work directly with the binary data, or convert to Base64 to send over the network

                  ...
                  delete[]buffer;
                  

                  MCVE:

                  #include <iostream>
                  #include <fstream>
                  #include <vector>
                  #include <Windows.h>
                  #include <gdiplus.h>
                  
                  bool save_png_memory(HBITMAP hbitmap, std::vector<BYTE> &data)
                  {
                      Gdiplus::Bitmap bmp(hbitmap, nullptr);
                  
                      //write to IStream
                      IStream* istream = nullptr;
                      CreateStreamOnHGlobal(NULL, TRUE, &istream);
                  
                      CLSID clsid_png;
                      CLSIDFromString(L"{557cf406-1a04-11d3-9a73-0000f81ef32e}", &clsid_png);
                      Gdiplus::Status status = bmp.Save(istream, &clsid_png);
                      if(status != Gdiplus::Status::Ok)
                          return false;
                  
                      //get memory handle associated with istream
                      HGLOBAL hg = NULL;
                      GetHGlobalFromStream(istream, &hg);
                  
                      //copy IStream to buffer
                      int bufsize = GlobalSize(hg);
                      data.resize(bufsize);
                  
                      //lock & unlock memory
                      LPVOID pimage = GlobalLock(hg);
                      memcpy(&data[0], pimage, bufsize);
                      GlobalUnlock(hg);
                  
                      istream->Release();
                      return true;
                  }
                  
                  int main()
                  {
                      CoInitialize(NULL);
                  
                      ULONG_PTR token;
                      Gdiplus::GdiplusStartupInput tmp;
                      Gdiplus::GdiplusStartup(&token, &tmp, NULL);
                  
                      //take screenshot
                      RECT rc;
                      GetClientRect(GetDesktopWindow(), &rc);
                      auto hdc = GetDC(0);
                      auto memdc = CreateCompatibleDC(hdc);
                      auto hbitmap = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
                      auto oldbmp = SelectObject(memdc, hbitmap);
                      BitBlt(memdc, 0, 0, rc.right, rc.bottom, hdc, 0, 0, SRCCOPY);
                      SelectObject(memdc, oldbmp);
                      DeleteDC(memdc);
                      ReleaseDC(0, hdc);
                  
                      //save as png
                      std::vector<BYTE> data;
                      if(save_png_memory(hbitmap, data))
                      {
                          //write from memory to file for testing:
                          std::ofstream fout("test.png", std::ios::binary);
                          fout.write((char*)data.data(), data.size());
                      }
                      DeleteObject(hbitmap);
                  
                      Gdiplus::GdiplusShutdown(token);
                      CoUninitialize();
                  
                      return 0;
                  }
                  

                  这篇关于C++ gdi::Bitmap to PNG Image in memory的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:从内存缓冲区创建 HBITMAP 下一篇:高效获取windows桌面截图

                  相关文章

                      <bdo id='DPjdp'></bdo><ul id='DPjdp'></ul>
                    1. <small id='DPjdp'></small><noframes id='DPjdp'>

                    2. <tfoot id='DPjdp'></tfoot>
                      <i id='DPjdp'><tr id='DPjdp'><dt id='DPjdp'><q id='DPjdp'><span id='DPjdp'><b id='DPjdp'><form id='DPjdp'><ins id='DPjdp'></ins><ul id='DPjdp'></ul><sub id='DPjdp'></sub></form><legend id='DPjdp'></legend><bdo id='DPjdp'><pre id='DPjdp'><center id='DPjdp'></center></pre></bdo></b><th id='DPjdp'></th></span></q></dt></tr></i><div id='DPjdp'><tfoot id='DPjdp'></tfoot><dl id='DPjdp'><fieldset id='DPjdp'></fieldset></dl></div>

                    3. <legend id='DPjdp'><style id='DPjdp'><dir id='DPjdp'><q id='DPjdp'></q></dir></style></legend>