C ++从位图获取图像缓冲区

问题描述 投票:1回答:1

我想拍摄PNG格式的屏幕截图。但是我有一个严重的问题,我认为这对教授来说似乎很容易。1。如何从位图(类)获取图像缓冲区。2.我使用的是多显示器,分辨率也不同。如何获得全屏分辨率。

实现:

#pragma comment (lib, "gdiplus.lib")
#include "stdafx.h"
#include <afxwin.h>
#include <stdio.h>
#include <tchar.h>
#include <gdiplus.h>
using namespace Gdiplus;

DWORD PNGScreenshot();
INT GetEncoderClsid(const WCHAR * format, CLSID* pClsid);

INT GetEncoderClsid(const WCHAR * format, CLSID* pClsid)
{
    UINT num = 0;
    UINT size = 0;
    ImageCodecInfo* pImageCodecInfo = NULL;

    GetImageEncodersSize(&num, &size);
    if (size == 0)
        return -1;
    pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
    if (pImageCodecInfo == NULL)
        return -1;

    GetImageEncoders(num, size, pImageCodecInfo);

    for (UINT j = 0; j < num; j++)
    {
        if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
        {
            *pClsid = pImageCodecInfo[j].Clsid;
            free(pImageCodecInfo);
            return j;
        }
    }

    free(pImageCodecInfo);
    return -1;
}
DWORD PNGScreenshot()
{
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    HDC hScreenDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);
    HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
    INT x = GetDeviceCaps(hScreenDC, HORZRES);
    INT y = GetDeviceCaps(hScreenDC, VERTRES);

    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, x, y);
    HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);

    StretchBlt(hMemoryDC, 0, 0, x, y, hScreenDC, 0, 0, x, y, SRCCOPY);
    hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);

    CLSID pngClsid;
    GetEncoderClsid(L"image/png", &pngClsid);

    Bitmap *bmp = new Bitmap(hBitmap, NULL);
    // Get Image Buffer from Bitmap
    // GetBufferFromBitmap(LPBYTE lpImageBuffer, Bitmap * bmp);
    // {
    //      1. Get Size of Bitmap
    //      2. Get Image buffer from Bitmap
    //      3. Copy Image buffer to lpImageBuffer
    // }
    // ... Do ...

    delete bmp;

    GdiplusShutdown(gdiplusToken);

    return GetLastError();
}

int _tmain(int argc, _TCHAR* argv[])
{
    PNGScreenshot();

    return 0;
}

这只是我的实现,那么还有其他方法可以将PNG屏幕快照用作缓冲区吗?

image-processing visual-c++ screenshot gdi+ screen-resolution
1个回答
0
投票

一个替代实现可能是使用IStream接口。使用Save方法使用IStream编解码器将位图存储到clsid_png对象,然后返回到图像FromStream。 @Barmak的MCVE使用memcpy而不是FromStream

© www.soinside.com 2019 - 2024. All rights reserved.