프로그래밍 방식으로 스크린 샷을 찍고 PNG로 저장

W2a

나는 꽤 오랫동안 다음 코드를 사용하고 있습니다.

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

#include <iostream>

using namespace std;

void CaptureScreen(const char* filename)
{
    HDC hScreenDC = GetDC(0);
    HDC hMemoryDC = CreateCompatibleDC(hScreenDC);

    int upper_left_x = GetSystemMetrics(SM_XVIRTUALSCREEN);
    int upper_left_y = GetSystemMetrics(SM_YVIRTUALSCREEN);

    int bitmap_dx = GetSystemMetrics(SM_CXVIRTUALSCREEN ) * 1.25f;
    int bitmap_dy = GetSystemMetrics(SM_CYVIRTUALSCREEN ) * 1.25f;

    // create file
    ofstream file(filename, ios::binary);
    if(!file) return;

    // save bitmap file headers
    BITMAPFILEHEADER fileHeader;
    BITMAPINFOHEADER infoHeader;

    fileHeader.bfType      = 0x4d42;
    fileHeader.bfSize      = 0;
    fileHeader.bfReserved1 = 0;
    fileHeader.bfReserved2 = 0;
    fileHeader.bfOffBits   = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    infoHeader.biSize          = sizeof(infoHeader);
    infoHeader.biWidth         = bitmap_dx;
    infoHeader.biHeight        = -bitmap_dy;
    infoHeader.biPlanes        = 1;
    infoHeader.biBitCount      = 16;
    infoHeader.biCompression   = BI_RGB;
    infoHeader.biSizeImage     = 0;
    infoHeader.biXPelsPerMeter = 0;
    infoHeader.biYPelsPerMeter = 0;
    infoHeader.biClrUsed       = 0;
    infoHeader.biClrImportant  = 0;

    file.write((char*)&fileHeader, sizeof(fileHeader));
    file.write((char*)&infoHeader, sizeof(infoHeader));

    // dibsection information
    BITMAPINFO info;
    info.bmiHeader = infoHeader;

    // ------------------
    // THE IMPORTANT CODE
    // ------------------
    // create a dibsection and blit the window contents to the bitmap

    BYTE* memory = 0;
    HBITMAP bitmap = CreateDIBSection(hScreenDC, &info, DIB_RGB_COLORS, (void**)&memory, 0, 0);
    SelectObject(hMemoryDC, bitmap);
    BitBlt(hMemoryDC, 0, 0, bitmap_dx, bitmap_dy, hScreenDC, upper_left_x, upper_left_y, SRCCOPY);
    DeleteDC(hMemoryDC);
    ReleaseDC(NULL, hScreenDC);

    // save dibsection data
    int bytes = (((16*bitmap_dx + 31) & (~31))/8)*bitmap_dy;
    file.write((const char *)memory, bytes);

    DeleteObject(bitmap);
}

int main()
{
    CaptureScreen("ok.jpg");

    return 0;
}

그러나 비트 맵이 압축되지 않은 상태로 저장되기 때문에 너무 큰 BMP 파일이 생성되는 것 같습니다.

스크린 샷을 캡처하여 PNG 형식의 버퍼에 저장하고 TCP 연결을 통해 전송하고 거기에 PNG 파일로 저장하는 방법을 찾고 있습니다.

나는 그것이 할당 함께 할 수있는 뭔가가 생각 BI_PNGinfoHeader.biCompression하고 다른 계산을 bytes하지만 정확하게 알아낼 수 없습니다.

W2a

http://lodev.org/lodepng/

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

#include <iostream>

#include "lodepng.h"

const int bits_per_pixel = 24;


using namespace std;

void CaptureScreen(const char* filename)
{
    HDC hScreenDC = GetDC(0);
    HDC hMemoryDC = CreateCompatibleDC(hScreenDC);

    int upper_left_x = GetSystemMetrics(SM_XVIRTUALSCREEN);
    int upper_left_y = GetSystemMetrics(SM_YVIRTUALSCREEN);

    int bitmap_dx = GetSystemMetrics(SM_CXVIRTUALSCREEN ) * 1.25f;
    int bitmap_dy = GetSystemMetrics(SM_CYVIRTUALSCREEN ) * 1.25f;

    // create file
    ofstream file(filename, ios::binary);
    if(!file) return;

    // save bitmap file headers
    BITMAPFILEHEADER fileHeader;
    BITMAPINFOHEADER infoHeader;

    fileHeader.bfType      = 0x4d42;
    fileHeader.bfSize      = 0;
    fileHeader.bfReserved1 = 0;
    fileHeader.bfReserved2 = 0;
    fileHeader.bfOffBits   = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    infoHeader.biSize          = sizeof(infoHeader);
    infoHeader.biWidth         = bitmap_dx;
    infoHeader.biHeight        = -bitmap_dy;
    infoHeader.biPlanes        = 1;
    infoHeader.biBitCount      = bits_per_pixel;
    infoHeader.biCompression   = BI_RGB;
    infoHeader.biSizeImage     = 0;
    infoHeader.biXPelsPerMeter = 0;
    infoHeader.biYPelsPerMeter = 0;
    infoHeader.biClrUsed       = 0;
    infoHeader.biClrImportant  = 0;

    file.write((char*)&fileHeader, sizeof(fileHeader));
    file.write((char*)&infoHeader, sizeof(infoHeader));

    // dibsection information
    BITMAPINFO info;
    info.bmiHeader = infoHeader; 

    // ------------------
    // THE IMPORTANT CODE
    // ------------------
    // create a dibsection and blit the window contents to the bitmap

    BYTE* memory = 0;
    HBITMAP bitmap = CreateDIBSection(hScreenDC, &info, DIB_RGB_COLORS, (void**)&memory, 0, 0);
    SelectObject(hMemoryDC, bitmap);
    BitBlt(hMemoryDC, 0, 0, bitmap_dx, bitmap_dy, hScreenDC, upper_left_x, upper_left_y, SRCCOPY);
    DeleteDC(hMemoryDC);
    ReleaseDC(NULL, hScreenDC);

    // save dibsection data
    int bytes = (((bits_per_pixel*bitmap_dx + 31) & (~31))/8)*bitmap_dy;
    file.write((const char *)memory, bytes);

    unsigned char *out_buffer;
    size_t out_buffer_len;

    unsigned error;
    if ( bits_per_pixel == 24 )
    {
        // convert memory from bgr format to rgb
        for ( unsigned i = 0; i< bytes-2; i+=3)
        {
            int tmp = memory[i+2];
            memory[i+2] = memory[i];
            memory[i] = tmp;
        }

        error = lodepng_encode24(&out_buffer,
                                          &out_buffer_len,
                                          memory,
                                          bitmap_dx,
                                          bitmap_dy);
    }

    if ( bits_per_pixel == 32 )
    {
        // convert memory from bgr format to rgb
        for ( unsigned i = 0; i< bytes-3; i+=4)
        {
            int tmp = memory[i+2];
            memory[i+2] = memory[i];
            memory[i] = tmp;
        }

        error = lodepng_encode32(&out_buffer,
                                          &out_buffer_len,
                                          memory,
                                          bitmap_dx,
                                          bitmap_dy);
    }


    if ( error )
    {
        std::cout << "error: " << error << '\n';
        return;
    }

    lodepng_save_file(out_buffer, out_buffer_len, "stam.png");




    // free(out);
    DeleteObject(bitmap);
}

int main()
{
    CaptureScreen("ok.jpg");

    return 0;
}

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

Powershell로 원격 스크린 샷을 찍는 방법

분류에서Dev

프로그래밍 방식으로 스크린 샷을 찍으면 Cardview의 반경이 사라집니다.

분류에서Dev

Swift 5 xcode 13을 사용하여 스크린 샷을 pdf 또는 고해상도 이미지로 저장

분류에서Dev

파이썬으로 스크린 샷을 찍는 방법?

분류에서Dev

프로그래밍 방식으로 스크린 샷을 찍으면 surfaceVIew의 콘텐츠가 캡처되지 않습니다.

분류에서Dev

프로그래밍 방식으로 ipython 노트북을 스크립트로 저장

분류에서Dev

Windows Phone에서 프로그래밍 방식으로 스크린 샷을 찍는 방법은 무엇입니까?

분류에서Dev

손으로 그린 선을 프로그래밍 방식으로 조작하는 가장 좋은 방법

분류에서Dev

프로그래밍 방식으로 iPad 홈 화면의 스크린 샷을 찍는 방법은 무엇입니까?

분류에서Dev

프로그래밍 방식으로 iPhone 스크린 샷

분류에서Dev

django --canvas 요소의 사용자 웹캠에서 찍은 스크린 샷을 파일에 업로드 및 저장

분류에서Dev

CutyCapt로 고해상도 스크린 샷을 찍는 방법

분류에서Dev

프로그램을 시작하고 GUI가 인스턴스화되면 자동 스크린 샷을 찍은 다음 프로그램을 닫습니다.

분류에서Dev

WinJS는 프로그래밍 방식으로 앱의 스크린 샷을 찍습니다.

분류에서Dev

scrot으로 매시간 스크린 샷을 찍는 Cronjob

분류에서Dev

Swift에서 프로그래밍 방식으로 앱의 스크린 샷을 찍으려고 할 때 스크린 샷이 흰색으로 표시되는 이유는 무엇입니까?

분류에서Dev

Android에서 열린 현재 활동의 스크린 샷을 프로그래밍 방식으로 찍는 방법은 무엇입니까?

분류에서Dev

iOS 프로그래밍 방식으로 GPUImageview로 스크린 샷 찍기

분류에서Dev

유형을 저장하고 프로그래밍 방식으로 다른 변수를 저장된 유형으로 캐스팅

분류에서Dev

프로그래밍 방식으로 화면의 특정 부분 스크린 샷

분류에서Dev

특정 셀의 스크린 샷을 찍고 이미지 파일로 저장하는 Excel 매크로

분류에서Dev

이미지를 탭할 때 프로그래밍 방식으로 uwp에서 스크린 샷을 찍으려고합니다.

분류에서Dev

다른 시간 간격으로 Selenium에서 스크린 샷을 찍고 다른 장소에 저장하는 방법 오류

분류에서Dev

Python : 스크린 샷을 찍고 저장하는 가장 빠른 방법

분류에서Dev

스크린 샷을 찍고 SQL VB.NET에 저장

분류에서Dev

프로그래밍 방식으로 장면의 스냅 샷을 캡처 할 수 있습니까?

분류에서Dev

Python 모듈 pyautogui를 사용하여 스크린 샷을 찍고 날짜 및 시간별로 .png 파일 이름을 자동으로 지정합니다.

분류에서Dev

Python을 사용하여 스크린 샷을 배열로 저장

분류에서Dev

Android Studio에서 스크린 샷을 찍거나 이미지로 내 조각 앱으로 저장하려면 어떻게해야합니까?

Related 관련 기사

  1. 1

    Powershell로 원격 스크린 샷을 찍는 방법

  2. 2

    프로그래밍 방식으로 스크린 샷을 찍으면 Cardview의 반경이 사라집니다.

  3. 3

    Swift 5 xcode 13을 사용하여 스크린 샷을 pdf 또는 고해상도 이미지로 저장

  4. 4

    파이썬으로 스크린 샷을 찍는 방법?

  5. 5

    프로그래밍 방식으로 스크린 샷을 찍으면 surfaceVIew의 콘텐츠가 캡처되지 않습니다.

  6. 6

    프로그래밍 방식으로 ipython 노트북을 스크립트로 저장

  7. 7

    Windows Phone에서 프로그래밍 방식으로 스크린 샷을 찍는 방법은 무엇입니까?

  8. 8

    손으로 그린 선을 프로그래밍 방식으로 조작하는 가장 좋은 방법

  9. 9

    프로그래밍 방식으로 iPad 홈 화면의 스크린 샷을 찍는 방법은 무엇입니까?

  10. 10

    프로그래밍 방식으로 iPhone 스크린 샷

  11. 11

    django --canvas 요소의 사용자 웹캠에서 찍은 스크린 샷을 파일에 업로드 및 저장

  12. 12

    CutyCapt로 고해상도 스크린 샷을 찍는 방법

  13. 13

    프로그램을 시작하고 GUI가 인스턴스화되면 자동 스크린 샷을 찍은 다음 프로그램을 닫습니다.

  14. 14

    WinJS는 프로그래밍 방식으로 앱의 스크린 샷을 찍습니다.

  15. 15

    scrot으로 매시간 스크린 샷을 찍는 Cronjob

  16. 16

    Swift에서 프로그래밍 방식으로 앱의 스크린 샷을 찍으려고 할 때 스크린 샷이 흰색으로 표시되는 이유는 무엇입니까?

  17. 17

    Android에서 열린 현재 활동의 스크린 샷을 프로그래밍 방식으로 찍는 방법은 무엇입니까?

  18. 18

    iOS 프로그래밍 방식으로 GPUImageview로 스크린 샷 찍기

  19. 19

    유형을 저장하고 프로그래밍 방식으로 다른 변수를 저장된 유형으로 캐스팅

  20. 20

    프로그래밍 방식으로 화면의 특정 부분 스크린 샷

  21. 21

    특정 셀의 스크린 샷을 찍고 이미지 파일로 저장하는 Excel 매크로

  22. 22

    이미지를 탭할 때 프로그래밍 방식으로 uwp에서 스크린 샷을 찍으려고합니다.

  23. 23

    다른 시간 간격으로 Selenium에서 스크린 샷을 찍고 다른 장소에 저장하는 방법 오류

  24. 24

    Python : 스크린 샷을 찍고 저장하는 가장 빠른 방법

  25. 25

    스크린 샷을 찍고 SQL VB.NET에 저장

  26. 26

    프로그래밍 방식으로 장면의 스냅 샷을 캡처 할 수 있습니까?

  27. 27

    Python 모듈 pyautogui를 사용하여 스크린 샷을 찍고 날짜 및 시간별로 .png 파일 이름을 자동으로 지정합니다.

  28. 28

    Python을 사용하여 스크린 샷을 배열로 저장

  29. 29

    Android Studio에서 스크린 샷을 찍거나 이미지로 내 조각 앱으로 저장하려면 어떻게해야합니까?

뜨겁다태그

보관