如何截取屏幕截图并将其保存为Windows上的JPEG?

前端之家收集整理的这篇文章主要介绍了如何截取屏幕截图并将其保存为Windows上的JPEG?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图找到一个(有点)简单的方法来在窗口上截图,并将得到的HBITMAP保存为JPEG.这里的棘手部分是,由于代码是C,我不能使用GDI,因为代码是一个更大的程序的模块,我不能使用外部lib(如libjpeg).

代码需要截图并返回HBITMAP.将该位图保存到文件中很容易.问题是位图是2或3mb.

HDC hDCMem = CreateCompatibleDC(NULL);
HBITMAP hBmp;
RECT rect;
HDC hDC;
HGdioBJ hOld;    

GetWindowRect(hWnd,& 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;

任何想法如何做到这一点?
非常感谢,任何帮助都不胜感激

编辑:
由于我们进入GDI的方向,我以为我会发布代码iv C,可以使用截图,并将其转换为使用GDI的JPEG.如果有人知道如何使用FLAT GDI来实现这一点,我将不胜感激.
码:

#include <windows.h>
#include <stdio.h>
#include <gdiplus.h>

using namespace Gdiplus;


int GetEncoderClsid(WCHAR *format,CLSID *pClsid)
{
    unsigned int num = 0,size = 0;
    GetImageEncodeRSSize(&num,&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 < 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(&gdiplusToken,&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,&r);
    GetWindowRect(hMyWnd,&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,};

    // create a container and take the screenshot
    HBITMAP hbmCapture = CreateDIBSection(dc,&bmiCapture,DIB_PAL_COLORS,(LPVOID *)&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,h,dc,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 = &uQuality;
    GetEncoderClsid(L"image/jpeg",&imageCLSID);
    iRes = (pScreenShot->Save(lpszFilename,&imageCLSID,&encoderParams) == Ok);
    delete pScreenShot;
    DeleteObject(hbmCapture);
    GdiplusShutdown(gdiplusToken);
    return iRes;

}
好的,经过这么多的努力,这里的答案是:
int SaveJpeg(HBITMAP hBmp,LPCWSTR lpszFilename,ULONG uQuality)
{
    ULONG *pBitmap = NULL;
    CLSID imageCLSID;
    EncoderParameters encoderParams;
    int iRes = 0;

    typedef Status (WINAPI *pGdipCreateBitmapFromHBITMAP)(HBITMAP,HPALETTE,ULONG**);
    pGdipCreateBitmapFromHBITMAP lGdipCreateBitmapFromHBITMAP;

    typedef Status (WINAPI *pGdipSaveImageToFile)(ULONG *,const WCHAR*,const CLSID*,const EncoderParameters*);
    pGdipSaveImageToFile lGdipSaveImageToFile;

    // load GdipCreateBitmapFromHBITMAP
    lGdipCreateBitmapFromHBITMAP = (pGdipCreateBitmapFromHBITMAP)GetProcAddress(hModuleThread,"GdipCreateBitmapFromHBITMAP");
    if(lGdipCreateBitmapFromHBITMAP == NULL)
    {
        // error
        return 0;
    }

    // load GdipSaveImageToFile
    lGdipSaveImageToFile = (pGdipSaveImageToFile)GetProcAddress(hModuleThread,"GdipSaveImageToFile");
    if(lGdipSaveImageToFile == NULL)
    {
        // error
        return 0;
    }

        lGdipCreateBitmapFromHBITMAP(hBmp,&pBitmap);

       iRes = GetEncoderClsid(L"image/jpeg",&imageCLSID);
       if(iRes == -1)
    {
        // error
        return 0;
    }
    encoderParams.Count = 1;
    encoderParams.Parameter[0].NumberOfValues = 1;
    encoderParams.Parameter[0].Guid  = EncoderQuality;
    encoderParams.Parameter[0].Type  = EncoderParameterValueTypeLong;
    encoderParams.Parameter[0].Value = &uQuality;

    lGdipSaveImageToFile(pBitmap,lpszFilename,&encoderParams);


    return 1;
}

>什么是hModuleThread?看看在here.你可以用GetModuleHandle()
>什么是GetEncoderClsid?看here.

现在的问题是,如何将编码的pBitmap(作为jpeg)保存到BYTE缓冲区?

原文链接:https://www.f2er.com/windows/370816.html

猜你在找的Windows相关文章