본문 바로가기
카테고리 없음

전체 화면 캡처 기능 직접 구현하기 – BMP 아닌 PNG 저장까지!

by 세상을읽는눈 2025. 4. 9.
반응형

 

 

지난 글에서는 Visual Studio로 빈 Win32 프로젝트를 만들고, "Hello Capture!" 메시지를 띄워보는 첫 걸음을 마쳤습니다.
이번 글에서는 본격적으로 전체 화면을 캡처하고 PNG 파일로 저장하는 기능을 직접 구현해봅니다.


📌 목표 기능

  • 전체 화면을 캡처하여
  • PNG 형식으로 자동 저장
  • 파일명은 날짜+시간 기반 자동 생성

🔧 사용하는 기술

  • WinAPI: 화면 캡처 (BitBlt, GetDC, CreateCompatibleBitmap 등)
  • GDI+: PNG 저장 기능
  • C++ 및 Visual Studio (x64, 빈 프로젝트)

🧱 전체 코드 – main.cpp

#include <windows.h>
#include <gdiplus.h>
#include <string>
#include <ctime>

#pragma comment (lib,"Gdiplus.lib")

using namespace Gdiplus;

ULONG_PTR gdiplusToken;

void SaveHBITMAPToFile(HBITMAP hBitmap, const wchar_t* filename) {
    Gdiplus::Bitmap bmp(hBitmap, NULL);

    CLSID clsidEncoder;
    UINT numEncoders = 0;
    UINT size = 0;

    GetImageEncodersSize(&numEncoders, &size);
    if (size == 0) return;

    ImageCodecInfo* pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
    if (pImageCodecInfo == NULL) return;

    GetImageEncoders(numEncoders, size, pImageCodecInfo);
    for (UINT i = 0; i < numEncoders; ++i) {
        if (wcscmp(pImageCodecInfo[i].MimeType, L"image/png") == 0) {
            clsidEncoder = pImageCodecInfo[i].Clsid;
            break;
        }
    }
    bmp.Save(filename, &clsidEncoder, NULL);
    free(pImageCodecInfo);
}

int main() {
    GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    int screenX = GetSystemMetrics(SM_CXSCREEN);
    int screenY = GetSystemMetrics(SM_CYSCREEN);

    HDC hScreenDC = GetDC(NULL);
    HDC hMemDC = CreateCompatibleDC(hScreenDC);
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, screenX, screenY);
    SelectObject(hMemDC, hBitmap);

    BitBlt(hMemDC, 0, 0, screenX, screenY, hScreenDC, 0, 0, SRCCOPY);

    wchar_t filename[256];
    time_t now = time(0);
    tm localTime;
    localtime_s(&localTime, &now);
    wsprintf(filename, L"capture_%04d%02d%02d_%02d%02d%02d.png",
        localTime.tm_year + 1900, localTime.tm_mon + 1, localTime.tm_mday,
        localTime.tm_hour, localTime.tm_min, localTime.tm_sec);

    SaveHBITMAPToFile(hBitmap, filename);

    DeleteObject(hBitmap);
    DeleteDC(hMemDC);
    ReleaseDC(NULL, hScreenDC);
    GdiplusShutdown(gdiplusToken);

    MessageBox(NULL, L"전체 화면 캡처 완료!", L"캡처 도구", MB_OK);
    return 0;
}

✅ 실행 결과

프로그램을 실행하면 전체 화면이 자동으로 캡처되고, 아래처럼 파일이 저장됩니다.

📁 capture_20250409_145545.png

메시지 박스로 "전체 화면 캡처 완료!"도 함께 출력됩니다.


🧩 구현 포인트

  • GDI+는 PNG 저장을 위해 꼭 필요합니다.
  • BitBlt로 화면 이미지를 복사하고, Gdiplus::Bitmap.Save()로 저장하면 끝!
  • 실행한 디렉토리에 자동 저장되며, 날짜/시간을 기반으로 파일명이 자동 생성되어 덮어쓰는 일도 없습니다.

📝 다음 글 예고

다음 편에서는 이 캡처 기능을:

  • 단축키로 실행하거나
  • 트레이 아이콘으로 숨기거나
  • 지정 영역 캡처 기능을 붙여보려 합니다.

이 포스트는 GPT와 함께 개발 과정을 공유하며 작성했습니다.
실제 개발 환경에서 바로 동작하는 예제 코드와 함께, 실용적인 도구를 직접 만들어가보세요!


 

반응형