title: How can I take a screenshot and save it as JPEG on Windows?
body: <p>I'm trying to find a (somewhat) easy way to take a screenshot on window and save the resulting HBITMAP as a JPEG. The tricky part here is that since the code is in C I can't use GDI+ and since the code is a module for a bigger program I can't neither use an external lib (like libjpeg).</p>
  
  <p>This code takes a screenshot and returns a HBITMAP. Saving that bitmap into a file is easy. the problem is that the bitmap is 2 or 3mb.</p>
  
  <pre><code>HDC hDCMem = CreateCompatibleDC(NULL);
  HBITMAP hBmp;
  RECT rect;
  HDC hDC;
  HGDIOBJ hOld;    
  
  GetWindowRect(hWnd, &amp; rect);
  
  hBmp = NULL;
  
  {
      hDC = GetDC(hWnd);
      hBmp = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);
      ReleaseDC(hWnd, hDC);
  }
  
  hOld = SelectObject(hDCMem, hBmp);
  SendMessage(hWnd, WM_PRINT, (WPARAM) hDCMem, PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT | PRF_OWNED);
  
  SelectObject(hDCMem, hOld);
  DeleteObject(hDCMem);
  
  return hBmp;
  </code></pre>
  
  <p>any ideas on how to do this?
  thanks so much, any help is appreciated</p>
  
  <p>EDIT:
  Since we went in the direction of GDI+ I thought I'd post the code iv C++ that can take the screenshot and convert it to a JPEG using GDI+. If anyone knows how to achieve this using the FLAT GDI+ i'd appreciate the help.
  Code:</p>
  
  <pre><code>    #include &lt;windows.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;gdiplus.h&gt;
  
  using namespace Gdiplus;
  
  
  int GetEncoderClsid(WCHAR *format, CLSID *pClsid)
  {
      unsigned int num = 0,  size = 0;
      GetImageEncodersSize(&amp;num, &amp;size);
      if(size == 0) return -1;
      ImageCodecInfo *pImageCodecInfo = (ImageCodecInfo *)(malloc(size));
      if(pImageCodecInfo == NULL) return -1;
      GetImageEncoders(num, size, pImageCodecInfo);
      for(unsigned int j = 0; j &lt; num; ++j)
      {
          if(wcscmp(pImageCodecInfo[j].MimeType, format) == 0){
              *pClsid = pImageCodecInfo[j].Clsid;
              free(pImageCodecInfo);
              return j;
          }    
      }
      free(pImageCodecInfo);
      return -1;
  }
  
  int GetScreeny(LPWSTR lpszFilename, ULONG uQuality) // by Napalm
  {
      ULONG_PTR gdiplusToken;
      GdiplusStartupInput gdiplusStartupInput;
      GdiplusStartup(&amp;gdiplusToken, &amp;gdiplusStartupInput, NULL);
      HWND hMyWnd = GetForegroundWindow(); // get my own window
      RECT  r;                             // the area we are going to capture 
      int w, h;                            // the width and height of the area
      HDC dc;                              // the container for the area
      int nBPP;
      HDC hdcCapture;
      LPBYTE lpCapture;
      int nCapture;
      int iRes;
      CLSID imageCLSID;
      Bitmap *pScreenShot;
      HGLOBAL hMem;
      int result;
  
      // get the area of my application's window  
      //GetClientRect(hMyWnd, &amp;r);
      GetWindowRect(hMyWnd, &amp;r);
      dc = GetWindowDC(hMyWnd);//   GetDC(hMyWnd) ;
      w = r.right - r.left;
      h = r.bottom - r.top;
      nBPP = GetDeviceCaps(dc, BITSPIXEL);
      hdcCapture = CreateCompatibleDC(dc);
  
  
      // create the buffer for the screenshot
      BITMAPINFO bmiCapture = {
            sizeof(BITMAPINFOHEADER), w, -h, 1, nBPP, BI_RGB, 0, 0, 0, 0, 0,
      };
  
      // create a container and take the screenshot
      HBITMAP hbmCapture = CreateDIBSection(dc, &amp;bmiCapture,
          DIB_PAL_COLORS, (LPVOID *)&amp;lpCapture, NULL, 0);
  
      // failed to take it
      if(!hbmCapture)
      {
          DeleteDC(hdcCapture);
          DeleteDC(dc);
          GdiplusShutdown(gdiplusToken);
          printf("failed to take the screenshot. err: %d\n", GetLastError());
          return 0;
      }
  
      // copy the screenshot buffer
      nCapture = SaveDC(hdcCapture);
      SelectObject(hdcCapture, hbmCapture);
      BitBlt(hdcCapture, 0, 0, w, h, dc, 0, 0, SRCCOPY);
      RestoreDC(hdcCapture, nCapture);
      DeleteDC(hdcCapture);
      DeleteDC(dc);
  
      // save the buffer to a file    
      pScreenShot = new Bitmap(hbmCapture, (HPALETTE)NULL);
      EncoderParameters encoderParams;
      encoderParams.Count = 1;
      encoderParams.Parameter[0].NumberOfValues = 1;
      encoderParams.Parameter[0].Guid  = EncoderQuality;
      encoderParams.Parameter[0].Type  = EncoderParameterValueTypeLong;
      encoderParams.Parameter[0].Value = &amp;uQuality;
      GetEncoderClsid(L"image/jpeg", &amp;imageCLSID);
      iRes = (pScreenShot-&gt;Save(lpszFilename, &amp;imageCLSID, &amp;encoderParams) == Ok);
      delete pScreenShot;
      DeleteObject(hbmCapture);
      GdiplusShutdown(gdiplusToken);
      return iRes;
  
  }
  </code></pre>