如何使用c ++为最小尺寸的窗口制作屏幕截图

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

我实现了一个制作屏幕截图的程序,但问题是图像大小大于6 MB。

我想进行校正以最小化图像尺寸。

这是我的职责

BOOL CALLBACK MonitorEnumProcCallback( HMONITOR hMonitor,  HDC DevC,LPRECT lprcMonitor,LPARAM dwData) 
{
        const char*BmpName;
        string BmpNameString;
        BmpNameString="screen.jpeg";
        BmpName= BmpNameString.c_str();
        MONITORINFO  info;
        info.cbSize = sizeof(MONITORINFO);
        BOOL monitorInfo = GetMonitorInfo(hMonitor, &info);
        if (monitorInfo) {
         DWORD Width = info.rcMonitor.right - info.rcMonitor.left;
         DWORD Height = info.rcMonitor.bottom - info.rcMonitor.top;
         DWORD FileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 3 * Width * Height;
         char *BmpFileData = (char*)GlobalAlloc(0x0040, FileSize); 
         PBITMAPFILEHEADER BFileHeader = (PBITMAPFILEHEADER)BmpFileData;
         PBITMAPINFOHEADER  BInfoHeader = (PBITMAPINFOHEADER)&BmpFileData[sizeof(BITMAPFILEHEADER)];
         BFileHeader->bfType = 0x4D42; // BM
         BFileHeader->bfSize = sizeof(BITMAPFILEHEADER);
         BFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
         BInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
         BInfoHeader->biPlanes = 1;
         BInfoHeader->biBitCount = 24;
         BInfoHeader->biCompression = BI_RGB;
         BInfoHeader->biHeight = Height;
         BInfoHeader->biWidth = Width;
         RGBTRIPLE *Image = (RGBTRIPLE*)&BmpFileData[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
         RGBTRIPLE color;
         HDC CaptureDC = CreateCompatibleDC(DevC);
         HBITMAP CaptureBitmap = CreateCompatibleBitmap(DevC, Width, Height);
         SelectObject(CaptureDC, CaptureBitmap);
         BitBlt(CaptureDC, 0, 0, Width, Height, DevC, info.rcMonitor.left, info.rcMonitor.top, SRCCOPY | CAPTUREBLT);
         GetDIBits(CaptureDC, CaptureBitmap, 0, Height, Image, (LPBITMAPINFO)BInfoHeader, DIB_RGB_COLORS);
         DWORD Junk;
         HANDLE FH = CreateFileA(BmpName, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0);
         WriteFile(FH, BmpFileData, FileSize, &Junk, 0);
         CloseHandle(FH);
         GlobalFree(BmpFileData);
        }
        return TRUE;
    }

data

c++ winapi bitmap
1个回答
0
投票

如果您不介意,则可以使用下面的GDI +方法来获得相对较小的尺寸:

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

using namespace Gdiplus;
using namespace std;
#pragma comment(lib, "Gdiplus.lib")

int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
    UINT  num = 0;          // number of image encoders
    UINT  size = 0;         // size of the image encoder array in bytes

    ImageCodecInfo* pImageCodecInfo = NULL;

    GetImageEncodersSize(&num, &size);
    if (size == 0)
        return -1;  // Failure

    pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
    if (pImageCodecInfo == NULL)
        return -1;  // Failure

    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;  // Success
        }
    }

    free(pImageCodecInfo);
    return -1;  // Failure
}

BOOL CALLBACK MonitorEnumProcCallback(HMONITOR hMonitor, HDC DevC, LPRECT lprcMonitor, LPARAM dwData)
{
    wstring BmpNameString = L"screen.jpeg";
    MONITORINFO  info;
    info.cbSize = sizeof(MONITORINFO);
    BOOL monitorInfo = GetMonitorInfo(hMonitor, &info);
    if (monitorInfo) {
        DWORD Width = info.rcMonitor.right - info.rcMonitor.left;
        DWORD Height = info.rcMonitor.bottom - info.rcMonitor.top;
        //DWORD FileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 3 * Width * Height;
        //char* BmpFileData = (char*)GlobalAlloc(0x0040, FileSize);
        //PBITMAPFILEHEADER BFileHeader = (PBITMAPFILEHEADER)BmpFileData;
        //PBITMAPINFOHEADER  BInfoHeader = (PBITMAPINFOHEADER)&BmpFileData[sizeof(BITMAPFILEHEADER)];
        //BFileHeader->bfType = 0x4D42; // BM
        //BFileHeader->bfSize = sizeof(BITMAPFILEHEADER);
        //BFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
        //BInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
        //BInfoHeader->biPlanes = 1;
        //BInfoHeader->biBitCount = 24;
        //BInfoHeader->biCompression = BI_RLE8;
        //BInfoHeader->biHeight = Height;
        //BInfoHeader->biWidth = Width;
        //RGBTRIPLE* Image = (RGBTRIPLE*)&BmpFileData[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
        //RGBTRIPLE color;

        HDC CaptureDC = CreateCompatibleDC(DevC);
        HBITMAP CaptureBitmap = CreateCompatibleBitmap(DevC, Width, Height);
        HGDIOBJ old_obj = SelectObject(CaptureDC, CaptureBitmap);
        BitBlt(CaptureDC, 0, 0, Width, Height, DevC, info.rcMonitor.left, info.rcMonitor.top, SRCCOPY | CAPTUREBLT);
        //GetDIBits(CaptureDC, CaptureBitmap, 0, Height, Image, (LPBITMAPINFO)BInfoHeader, DIB_RGB_COLORS);
        /*DWORD Junk;
        HANDLE FH = CreateFileA(BmpName, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0);
        WriteFile(FH, BmpFileData, FileSize, &Junk, 0);
        CloseHandle(FH);
        GlobalFree(BmpFileData);*/
        Gdiplus::Bitmap bitmap(CaptureBitmap, NULL);

        CLSID pngClsid;
        GetEncoderClsid(L"image/jpeg", &pngClsid);
        bitmap.Save(BmpNameString.c_str(), &pngClsid, NULL);

        SelectObject(CaptureDC, old_obj);
        DeleteDC(CaptureDC);
        ReleaseDC(NULL, DevC);
        DeleteObject(CaptureBitmap);
    }
    return TRUE;
}
int main()
{
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    HDC hdc = GetDC(NULL);

    EnumDisplayMonitors(hdc,NULL, MonitorEnumProcCallback,NULL);

    ReleaseDC(NULL,hdc);
    GdiplusShutdown(gdiplusToken);
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.