savers: provides a background setting.

Allow users to set a custom background with a saver.

API:
- Result Saver::background(std::unique_ptr<Paint> paint);
This commit is contained in:
Hermet Park 2023-11-13 19:10:20 +09:00
parent 5129b05023
commit 27843d2557
7 changed files with 44 additions and 22 deletions

View file

@ -1804,6 +1804,15 @@ class TVG_API Saver final
public:
~Saver();
/**
* @brief Sets the base background content for the saved image.
*
* @param[in] paint The paint to be drawn as the background image for the saving paint.
*
* @note Experimental API
*/
Result background(std::unique_ptr<Paint> paint) noexcept;
/**
* @brief Exports the given @p paint data to the given @p path
*

View file

@ -34,7 +34,7 @@ public:
virtual ~SaveModule() {}
virtual bool save(Paint* paint, const string& path, bool compress) = 0;
virtual bool save(Animation* animation, const string& path, uint32_t quality, uint32_t fps) = 0;
virtual bool save(Animation* animation, Paint* bg, const string& path, uint32_t quality, uint32_t fps) = 0;
virtual bool close() = 0;
};

View file

@ -37,9 +37,12 @@
struct Saver::Impl
{
SaveModule* saveModule = nullptr;
Paint* bg = nullptr;
~Impl()
{
delete(saveModule);
delete(bg);
}
};
@ -139,7 +142,16 @@ Result Saver::save(std::unique_ptr<Paint> paint, const string& path, bool compre
}
Result Saver::save(std::unique_ptr<Animation> animation, const string& path, uint32_t quality, uint32_t fps) noexcept
Result Saver::background(unique_ptr<Paint> paint) noexcept
{
delete(pImpl->bg);
pImpl->bg = paint.release();
return Result::Success;
}
Result Saver::save(unique_ptr<Animation> animation, const string& path, uint32_t quality, uint32_t fps) noexcept
{
auto a = animation.release();
if (!a) return Result::MemoryCorruption;
@ -156,7 +168,7 @@ Result Saver::save(std::unique_ptr<Animation> animation, const string& path, uin
}
if (auto saveModule = _find(path)) {
if (saveModule->save(a, path, quality, fps)) {
if (saveModule->save(a, pImpl->bg, path, quality, fps)) {
pImpl->saveModule = saveModule;
return Result::Success;
} else {

View file

@ -42,13 +42,7 @@ void GifSaver::run(unsigned tid)
buffer = (uint32_t*)realloc(buffer, sizeof(uint32_t) * w * h);
canvas->target(buffer, w, w, h, tvg::SwCanvas::ABGR8888);
//base white background
auto bg = Shape::gen();
bg->appendRect(0, 0, vsize[0], vsize[1]);
bg->fill(255, 255, 255);
canvas->push(std::move(bg));
canvas->push(cast(bg));
canvas->push(cast(animation->picture()));
//use the default fps
@ -81,6 +75,8 @@ void GifSaver::run(unsigned tid)
}
if (!GifEnd(&writer)) TVGERR("GIF_SAVER", "Failed gif encoding");
this->bg = nullptr;
}
@ -98,6 +94,9 @@ bool GifSaver::close()
{
this->done();
delete(bg);
bg = nullptr;
delete(animation);
animation = nullptr;
@ -118,7 +117,7 @@ bool GifSaver::save(TVG_UNUSED Paint* paint, TVG_UNUSED const string& path, TVG_
}
bool GifSaver::save(Animation* animation, const string& path, TVG_UNUSED uint32_t quality, uint32_t fps)
bool GifSaver::save(Animation* animation, Paint* bg, const string& path, TVG_UNUSED uint32_t quality, uint32_t fps)
{
close();
@ -140,6 +139,7 @@ bool GifSaver::save(Animation* animation, const string& path, TVG_UNUSED uint32_
if (!this->path) return false;
this->animation = animation;
if (bg) this->bg = bg->duplicate();
this->fps = static_cast<float>(fps);
TaskScheduler::request(this);

View file

@ -34,6 +34,7 @@ class GifSaver : public SaveModule, public Task
private:
uint32_t* buffer = nullptr;
Animation* animation = nullptr;
Paint* bg = nullptr;
char *path = nullptr;
float vsize[2] = {0.0f, 0.0f};
float fps = 0.0f;
@ -44,7 +45,7 @@ public:
~GifSaver();
bool save(Paint* paint, const string& path, bool compress) override;
bool save(Animation* animation, const string& path, uint32_t quality, uint32_t fps) override;
bool save(Animation* animation, Paint* bg, const string& path, uint32_t quality, uint32_t fps) override;
bool close() override;
};

View file

@ -780,15 +780,14 @@ bool TvgSaver::close()
{
this->done();
if (paint) {
delete(paint);
paint = nullptr;
}
if (path) {
free(path);
path = nullptr;
}
delete(paint);
paint = nullptr;
free(path);
path = nullptr;
buffer.reset();
return true;
}
@ -822,7 +821,7 @@ bool TvgSaver::save(Paint* paint, const string& path, bool compress)
}
bool TvgSaver::save(TVG_UNUSED Animation* animation, TVG_UNUSED const string& path, TVG_UNUSED uint32_t quality, TVG_UNUSED uint32_t fps)
bool TvgSaver::save(TVG_UNUSED Animation* animation, TVG_UNUSED Paint* bg, TVG_UNUSED const string& path, TVG_UNUSED uint32_t quality, TVG_UNUSED uint32_t fps)
{
TVGLOG("TVG_SAVER", "Animation is not supported.");
return false;

View file

@ -35,6 +35,7 @@ class TvgSaver : public SaveModule, public Task
private:
Array<TvgBinByte> buffer;
Paint* paint = nullptr;
Paint* bg = nullptr;
char *path = nullptr;
uint32_t headerSize;
float vsize[2] = {0.0f, 0.0f};
@ -71,7 +72,7 @@ public:
~TvgSaver();
bool save(Paint* paint, const string& path, bool compress) override;
bool save(Animation* animation, const string& path, uint32_t quality, uint32_t fps) override;
bool save(Animation* animation, Paint* bg, const string& path, uint32_t quality, uint32_t fps) override;
bool close() override;
};