Add SaveImageResource implementation for GDI

This commit is contained in:
kevle 2021-06-10 20:40:47 +02:00
parent 5764bbab19
commit 7bdeb96649

View File

@ -710,7 +710,7 @@ namespace olc
ImageLoader() = default; ImageLoader() = default;
virtual ~ImageLoader() = default; virtual ~ImageLoader() = default;
virtual olc::rcode LoadImageResource(olc::Sprite* spr, const std::string& sImageFile, olc::ResourcePack* pack) = 0; 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: public:
olc::rcode LoadFromFile(const std::string& sImageFile, olc::ResourcePack* pack = nullptr); olc::rcode LoadFromFile(const std::string& sImageFile, olc::ResourcePack* pack = nullptr);
olc::rcode SaveToFile(const std::string& sImageFile) const;
public: public:
int32_t width = 0; int32_t width = 0;
@ -1364,6 +1365,10 @@ namespace olc
UNUSED(pack); UNUSED(pack);
return loader->LoadImageResource(this, sImageFile, 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() olc::Sprite* Sprite::Duplicate()
{ {
@ -4091,9 +4096,42 @@ namespace olc
return olc::rcode::OK; 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<Gdiplus::ImageCodecInfo> 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; 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; return olc::rcode::OK;
} }
@ -4278,7 +4316,7 @@ namespace olc
return olc::rcode::OK; 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; return olc::rcode::OK;
} }