diff --git a/Source/Image.cc b/Source/Image.cc index 8d3f461..b50eba4 100644 --- a/Source/Image.cc +++ b/Source/Image.cc @@ -20,6 +20,15 @@ using std::memcpy; using std::memcmp; +#ifdef ROBOT_OS_WIN + + #include + #include + #include + #pragma comment(lib, "gdiplus.lib") + +#endif + ROBOT_NS_BEGIN @@ -153,6 +162,96 @@ void Image::Destroy (void) //////////////////////////////////////////////////////////////////////////////// +bool Image::Load(const char *filename) +{ +#ifdef ROBOT_OS_WIN + + auto hwnd = GetDesktopWindow(); + auto hDesktopDC = GetDC(hwnd); + auto hMemoryDC = ::CreateCompatibleDC(hDesktopDC); + + // For convert filename to WCHAR + int size = 0; + + // Convert UTF8 string to wide-string + size = MultiByteToWideChar(CP_UTF8, 0, filename, (int)strlen(filename), nullptr, 0); + std::wstring filenameW(size, 0); + size = MultiByteToWideChar(CP_UTF8, 0, filename, (int)strlen(filename), &filenameW[0], size); + + // Initialize gdi+ + Gdiplus::GdiplusStartupInput si; + ULONG_PTR gdiplusToken; + GdiplusStartup(&gdiplusToken, &si, NULL); + + // Load image file + Gdiplus::Image* pGdiImage = new Gdiplus::Image(filenameW.c_str()); + + // Converting to bitmap + HBITMAP hBitmap; + Gdiplus::Bitmap* pGdiBitmap = static_cast(pGdiImage); + pGdiBitmap->GetHBITMAP(Gdiplus::Color(0, 0, 0), &hBitmap); + + RESET(*this); + if (Create(pGdiImage->GetWidth(), pGdiImage->GetHeight()) == false) + { + delete pGdiImage; + Gdiplus::GdiplusShutdown(gdiplusToken); + return false; + } + + bool bFail = true; + HDC hCompatibleDC = nullptr; + HGDIOBJ hOldObj = nullptr; + do + { + struct BITMAPINFO3 + { + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[260]; + } bmi; + + hCompatibleDC = CreateCompatibleDC(hMemoryDC); + if (!hCompatibleDC) + break; + + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biBitCount = 0; + if (!GetDIBits(hCompatibleDC, hBitmap, 0, 0, nullptr, (LPBITMAPINFO)&bmi, DIB_RGB_COLORS)) + break; + + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biHeight = -bmi.bmiHeader.biHeight; + + hOldObj = SelectObject(hCompatibleDC, hBitmap); + if (!(GetDIBits(hCompatibleDC, hBitmap, 0, -bmi.bmiHeader.biHeight, GetData(), (LPBITMAPINFO)&bmi, DIB_RGB_COLORS))) + break; + + bFail = false; + } while (false); + + if (hOldObj) + SelectObject(hCompatibleDC, hOldObj); + if (hCompatibleDC) + DeleteDC(hCompatibleDC); + if (hMemoryDC) + DeleteDC(hMemoryDC); + if (pGdiImage) + delete pGdiImage; + + // Shutdown gdi+ + Gdiplus::GdiplusShutdown(gdiplusToken); + + return (bFail == false); + +#endif + + // #TODO implement function for MacOS & Linux + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// + Color Image::GetPixel (const Point& point) const { return GetPixel (point.X, point.Y); diff --git a/Source/Image.h b/Source/Image.h index cbc8609..f104f0b 100644 --- a/Source/Image.h +++ b/Source/Image.h @@ -46,6 +46,8 @@ class ROBOT_EXPORT Image bool Create (uint16 w, uint16 h); void Destroy (void); + bool Load (const char* filename); + uint16 GetWidth (void) const { return mWidth; } uint16 GetHeight (void) const { return mHeight; } uint32 GetLength (void) const { return mLength; }