From 7bdeb9664966c0f81c2b76abc83225bd17c055ce Mon Sep 17 00:00:00 2001 From: kevle Date: Thu, 10 Jun 2021 20:40:47 +0200 Subject: [PATCH] Add SaveImageResource implementation for GDI --- olcPixelGameEngine.h | 48 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/olcPixelGameEngine.h b/olcPixelGameEngine.h index 48a9be5..aa11acd 100644 --- a/olcPixelGameEngine.h +++ b/olcPixelGameEngine.h @@ -710,7 +710,7 @@ namespace olc ImageLoader() = default; virtual ~ImageLoader() = default; virtual olc::rcode LoadImageResource(olc::Sprite* spr, const std::string& sImageFile, olc::ResourcePack* pack) = 0; - virtual olc::rcode SaveImageResource(olc::Sprite* spr, const std::string& sImageFile) = 0; + virtual olc::rcode SaveImageResource(const olc::Sprite* spr, const std::string& sImageFile) = 0; }; @@ -728,6 +728,7 @@ namespace olc public: olc::rcode LoadFromFile(const std::string& sImageFile, olc::ResourcePack* pack = nullptr); + olc::rcode SaveToFile(const std::string& sImageFile) const; public: int32_t width = 0; @@ -1364,6 +1365,10 @@ namespace olc UNUSED(pack); return loader->LoadImageResource(this, sImageFile, pack); } + olc::rcode Sprite::SaveToFile(const std::string& sImageFile) const + { + return loader->SaveImageResource(this, sImageFile); + } olc::Sprite* Sprite::Duplicate() { @@ -4091,9 +4096,42 @@ namespace olc return olc::rcode::OK; } - olc::rcode SaveImageResource(olc::Sprite* spr, const std::string& sImageFile) override + olc::rcode SaveImageResource(const olc::Sprite* spr, const std::string& sImageFile) override { - return olc::rcode::OK; + if (spr == nullptr) + return olc::rcode::FAIL; + + UINT num = 0; + UINT size = 0; + if (Gdiplus::GetImageEncodersSize(&num, &size) != Gdiplus::Status::Ok) + return olc::rcode::FAIL; + + // Round up or use one more element + int requiredSpace = size / num + 1; + std::vector infos(requiredSpace); + if (Gdiplus::GetImageEncoders(num, size, &infos[0]) != Gdiplus::Status::Ok) + return olc::rcode::FAIL; + infos.resize(num); + + // Search for PNG codec + auto pngIt = std::find_if(infos.begin(), infos.end(), [](const Gdiplus::ImageCodecInfo& ci) { + return wcscmp(ci.MimeType, L"image/png") == 0; + }); + + if (pngIt == infos.end()) return olc::rcode::FAIL; + + Gdiplus::Bitmap bmp(spr->width, spr->height, PixelFormat32bppARGB); + + for (int y = 0; y < spr->height; y++) + for (int x = 0; x < spr->width; x++) + { + Pixel p = spr->GetPixel(x, y); + Gdiplus::Color c(p.a, p.r, p.g, p.b); + if (bmp.SetPixel(x, y, c) != Gdiplus::Status::Ok) + return olc::rcode::FAIL; + } + + return bmp.Save(ConvertS2W(sImageFile).c_str(), &pngIt->Clsid) == Gdiplus::Status::Ok ? olc::rcode::OK : olc::rcode::FAIL; } }; } @@ -4215,7 +4253,7 @@ namespace olc return olc::rcode::FAIL; } - olc::rcode SaveImageResource(olc::Sprite* spr, const std::string& sImageFile) override + olc::rcode SaveImageResource(const olc::Sprite* spr, const std::string& sImageFile) override { return olc::rcode::OK; } @@ -4278,7 +4316,7 @@ namespace olc return olc::rcode::OK; } - olc::rcode SaveImageResource(olc::Sprite* spr, const std::string& sImageFile) override + olc::rcode SaveImageResource(const olc::Sprite* spr, const std::string& sImageFile) override { return olc::rcode::OK; }