在 C 中将 JPEG 屏幕截图保存为 BYTE 缓冲区

发布于 2024-07-25 11:27:58 字数 1786 浏览 1 评论 0原文

在我之前的一个问题中,我询问了由于只能使用 C 的限制,如何在不使用 GDI+ 的情况下截取屏幕截图并将其保存为 JPEG。 最后我在一些评论的帮助下自己回答了这个问题。 使用非常简洁的 C 版本的 GDI+(在运行时加载),我可以截取屏幕截图并将其作为 JPEG 保存到文件中。 现在,我如何将相同的屏幕截图保存到缓冲区而不是文件中? 无符号 char* 缓冲区? 这是需要转换的代码。

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, NULL, &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, &imageCLSID, &encoderParams);


    return 1;
}

谢谢您的帮助。

In one of my previous questions I asked how to take a screenshot and save it as JPEG without the use of GDI+ due to the constrains of having to use only C.
At the end I answered the question myself with the help of of some of the comments there.
Using a very terse C version of GDI+ (loaded at runtime) i can take a screenshot and save it as a JPEG to a file.
Now, how would I save that same screenshot not to a file but to a buffer? an unsigned char* buffer?
here's the code that needs to be converted.

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, NULL, &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, &imageCLSID, &encoderParams);


    return 1;
}

Thanks for the help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伴随着你 2024-08-01 11:27:58

您应该使用 GdipSaveImageToStream,而不是调用 GdipSaveImageToFile。 这将允许您将图像直接保存到流中,而不是将其写入文件。

有关详细信息,请参阅 GDI 图像函数

为了在内存中创建 IStream,您可以使用 CreateStreamOnHGlobal 。 它可以选择允许 IStream 分配自己的内存,或使用预分配的缓冲区。

Instead of calling GdipSaveImageToFile, you should use GdipSaveImageToStream. This will let you save the image into a stream directly, instead of writing it to a file.

See the GDI image functions for details.

In order to create an IStream in memory, you can use CreateStreamOnHGlobal. This has the option of allowing the IStream to allocate its own memory, or to use a pre-allocated buffer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文