🧼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 |
댓글