🧼C, C++/WinAPI, UX(UI)
png파일 출력하기 WINAPI C++
개발환경 >> Visual Studio
언어 >> C++17이상
운영체제 >> Windows10
안녕하세요~~!
이번에는 C++17이상에서 기존 winapi에서 BMP파일을 출력하는것이외의 PNG나 JPG같은 이미지파일들을
출력하는 방법에 대해서 포스팅하겠습니다!
우선은 기본적인 winapi에서 png나 jpg같은 이미지파일은 지원을 안해주지만, gdi+를 이용해서 자유자재로 다뤄보겠습니다.
GDI+를 이용해서 콘솔창에다가 이미지출력하기
#pragma comment(linker, "/SUBSYSTEM:CONSOLE") //콘솔프로그램으로 만들겠다고 명시
#pragma comment(lib, "gdiplus.lib") //gdiplus라이브러리
#include <sstream> //실행시간 출력을 위한 문자열스트림클래스
#include <chrono> //실행시간 측정을 위한 시간관련클래스
#include <windows.h> //windowsAPI사용을 위한 헤더
#include <gdiplus.h> //gdiplus사용을 위한 헤더
#include <conio.h> //_getch()함수사용을 위한 헤더
void ClsCursor() { //콘솔커서 거슬려서 없애는함수 만들었습니다.
CONSOLE_CURSOR_INFO curinfo;
GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &curinfo); //현재 콘솔커서값가져오기
curinfo.bVisible = FALSE; //안보이게 만들고
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &curinfo); //콘솔커서설정
}
void gdi(const wchar_t* filepath) {
ClsCursor();
HWND hwnd = GetConsoleWindow(); //콘솔창핸들값 구하기
HDC hdc = GetDC(hwnd); //핸들값으로 DC구하기
HDC MemoryDC = CreateCompatibleDC(hdc); //사용할수있는 DC생성
ULONG_PTR ptr; //Gdi+사용을 위한 포인터객체
Gdiplus::GdiplusStartupInput in; //gdi+입력값객체
Gdiplus::GdiplusStartup(&ptr, &in, 0); //시작
std::chrono::time_point start = std::chrono::system_clock::now(); //시간측정시작
Gdiplus::Image* b = Gdiplus::Image::FromFile(filepath); //이미지객체생성
Gdiplus::Graphics g(hdc); // DC를 이용한 그래픽객체 생성
Gdiplus::Rect rect; //위치값
rect.X = 0; //x좌표
rect.Y = 0; //y좌표
rect.Width = b->GetWidth(); //가로길이
rect.Height = b->GetHeight(); //세로길이
g.DrawImage(b, rect); //이미지그리기
ReleaseDC(hwnd, hdc); //메모리누수방지용
DeleteDC(hdc);
delete b;
std::chrono::duration<double> d = std::chrono::system_clock::now() - start; //시간측정끝
std::stringstream ss; //문자열스트림클래스정의
std::string str; //문자열클래스정의
ss << "수행하는데걸린시간:" << d.count() << "초"; //문자열스트림에 값넣기
ss >> str; //문자열스트림의 내용을 문자열에 넣기
MessageBoxA(0, str.c_str(), "", MB_OK); //메세지박스로 출력
if (_getch()) return; //콘솔창 멈추기
}
int main() {
gdiPlus(L"index.png");
}위와 같이 코드를 짰습니다~!

저는 위의 그림으로 지정했습니다!그러면 실행하면??!??!

여러번 실행해보니,,처음에는 0.012 ~ 0.014초정도로
나오다가계속실행하다보니0.009~0.011초가 많이 나왔습니다.
근데~! 저가 어디서 들었는데 gdi+랑 gdi를 합치면 속도가 빨라진다는소리를 들어서 이 부분도 직접 구현해보았습니다.
GDI+랑 GDI를 혼합해서 콘솔창에다가 이미지출력하기
#pragma comment(linker, "/SUBSYSTEM:CONSOLE") //콘솔프로그램으로 만들겠다고 명시
#pragma comment(lib, "gdiplus.lib") //gdiplus라이브러리
#include <sstream> //실행시간 출력을 위한 문자열스트림클래스
#include <chrono> //실행시간 측정을 위한 시간관련클래스
#include <windows.h> //windowsAPI사용을 위한 헤더
#include <gdiplus.h> //gdiplus사용을 위한 헤더
#include <conio.h> //_getch()함수사용을 위한 헤더
void ClsCursor() { //콘솔커서 거슬려서 없애는함수 만들었습니다.
CONSOLE_CURSOR_INFO curinfo;
GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &curinfo); //현재 콘솔커서값가져오기
curinfo.bVisible = FALSE; //안보이게 만들고
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &curinfo); //콘솔커서설정
}
void gdi(const wchar_t* filepath) {
ClsCursor();
HWND hwnd = GetConsoleWindow(); //콘솔창핸들값 구하기
HDC hdc = GetDC(hwnd); //핸들값으로 DC구하기
HDC MemoryDC = CreateCompatibleDC(hdc); //사용할수있는 DC생성
ULONG_PTR ptr; //Gdi+사용을 위한 포인터객체
Gdiplus::GdiplusStartupInput in; //gdi+입력값객체
Gdiplus::GdiplusStartup(&ptr, &in, 0); //시작
std::chrono::time_point start = std::chrono::system_clock::now(); //시간측정시작
Gdiplus::Bitmap* b = Gdiplus::Bitmap::FromFile(filepath); //파일로부터 비트맵받기
HBITMAP hBit; //HBITMAP구조체 선언
b->GetHBITMAP(Gdiplus::Color(0, 0, 0, 0), &hBit); 비트맵정보를 HBITMAP에 복사
HGDIOBJ obj = SelectObject(MemoryDC, hBit); //MemoryDC에다가 비트맵지정
BITMAP bit = { 0 }; //비트맵크기를 구하기위한 구조체
GetObject(hBit, sizeof BITMAP, &bit); //비트맵크기구하기위함
StretchBlt(hdc, 0, 0, bit.bmWidth, bit.bmHeight,
MemoryDC, 0, 0, bit.bmWidth, bit.bmHeight, SRCCOPY); //그리기
SelectObject(MemoryDC, obj); //밑부분은 메모리누수를 막기위함
DeleteObject(hBit);
ReleaseDC(hwnd, MemoryDC);
DeleteDC(hdc);
delete b;
std::chrono::duration<double> d = std::chrono::system_clock::now() - start; //시간측정끝
std::stringstream ss; //문자열스트림클래스정의
std::string str; //문자열클래스정의
ss << "수행하는데걸린시간:" << d.count() << "초"; //문자열스트림에 값넣기
ss >> str; //문자열스트림의 내용을 문자열에 넣기
MessageBoxA(0, str.c_str(), "", MB_OK); //메세지박스로 출력
if (_getch()) return; //콘솔창 멈추기
}
int main() {
gdi(L"index.png");
}위와 같이 코드를 짰습니다~!

저는 위의 그림으로 지정했습니다!
그러면 실행하면??!??!

여러번 실행해보니,,처음에는 0.011~ 0.012초정도로 나오다가
계속실행하다보니0.006~0.008초가 많이 나왔습니다.
확실히 GDI+만 썼을때는 0.0010가 많이 나왔고,
GDI+와 GDI를 혼합하여 썼을때는 0.008초가 많이 나오면서
약 0.002초가 절약되었습니다.
이것이 작은수치처럼 보여도 게임과 같이 같은이미지를 여러번 출력하게 된다면
시간이지날수록 그 격차는 점점더 커질수 있겠죠??
궁금한 부분이 있으면 댓글로 질문주세요!그럼 안녕~!~!~!
'🧼C, C++ > WinAPI, UX(UI)' 카테고리의 다른 글
| GDI+ 강좌 총정리 (0) | 2021.04.22 |
|---|---|
| 이미지 픽셀정보 직렬화 - C++ / GDI+ (0) | 2021.04.15 |
| 파일 자가복제 C++ #2 (0) | 2020.11.23 |
| WINAPI C++ #2 (0) | 2020.11.07 |
| WINAPI C++ #1 (0) | 2020.11.04 |
댓글