diff options
author | Florin Malita <fmalita@chromium.org> | 2018-07-13 15:47:27 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-07-15 02:52:38 +0000 |
commit | 0c604ed06b71dacaa7d685c0a833b8d07c2729b5 (patch) | |
tree | a494ae990a5ab318c35642a0b7ff4daf4ec1b2b5 /modules | |
parent | 6f6fdf91f66d2d98c099d832fd19d0c451c107b2 (diff) |
[skottie] Teach skottie_tool to dump frame SKPs
Similar to saving PNG frames, now we can save SKPs.
TBR=
Change-Id: I5791b564a1d3e70424e45e62034e559e677795f1
Reviewed-on: https://skia-review.googlesource.com/141320
Reviewed-by: Joe Gregorio <jcgregorio@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'modules')
-rw-r--r-- | modules/skottie/src/SkottieTool.cpp | 144 |
1 files changed, 108 insertions, 36 deletions
diff --git a/modules/skottie/src/SkottieTool.cpp b/modules/skottie/src/SkottieTool.cpp index 4038724f68..5e819b17e9 100644 --- a/modules/skottie/src/SkottieTool.cpp +++ b/modules/skottie/src/SkottieTool.cpp @@ -8,8 +8,10 @@ #include "SkCanvas.h" #include "SkCommandLineFlags.h" #include "SkGraphics.h" +#include "SkMakeUnique.h" #include "SkOSFile.h" #include "SkOSPath.h" +#include "SkPictureRecorder.h" #include "SkStream.h" #include "SkSurface.h" @@ -17,8 +19,9 @@ #include "Skottie.h" #endif -DEFINE_string2(input, i, nullptr, "Input .json file."); +DEFINE_string2(input , i, nullptr, "Input .json file."); DEFINE_string2(writePath, w, nullptr, "Output directory. Frames are names [0-9]{6}.png."); +DEFINE_string2(format , f, "png" , "Output format (png or skp)"); DEFINE_double(t0, 0, "Timeline start [0..1]."); DEFINE_double(t1, 1, "Timeline stop [0..1]."); @@ -27,8 +30,100 @@ DEFINE_double(fps, 30, "Decode frames per second."); DEFINE_int32(width , 800, "Render width."); DEFINE_int32(height, 600, "Render height."); +namespace { + +class Sink : public SkNoncopyable { +public: + virtual ~Sink() = default; + + bool handleFrame(const sk_sp<skottie::Animation>& anim, size_t idx) const { + const auto frame_file = SkStringPrintf("0%06d.%s", idx, fExtension.c_str()); + SkFILEWStream stream (SkOSPath::Join(FLAGS_writePath[0], frame_file.c_str()).c_str()); + + if (!stream.isValid()) { + SkDebugf("Could not open '%s/%s' for writing.\n", + FLAGS_writePath[0], frame_file.c_str()); + return false; + } + + return this->saveFrame(anim, &stream); + } + +protected: + Sink(const char* ext) : fExtension(ext) {} + + virtual bool saveFrame(const sk_sp<skottie::Animation>& anim, SkFILEWStream*) const = 0; + +private: + const SkString fExtension; + + using INHERITED = SkNoncopyable; +}; + +class PNGSink final : public Sink { +public: + PNGSink() + : INHERITED("png") + , fSurface(SkSurface::MakeRasterN32Premul(FLAGS_width, FLAGS_height)) { + if (!fSurface) { + SkDebugf("Could not allocate a %d x %d surface.\n", FLAGS_width, FLAGS_height); + } + } + + bool saveFrame(const sk_sp<skottie::Animation>& anim, SkFILEWStream* stream) const override { + if (!fSurface) return false; + + auto* canvas = fSurface->getCanvas(); + SkAutoCanvasRestore acr(canvas, true); + + canvas->concat(SkMatrix::MakeRectToRect(SkRect::MakeSize(anim->size()), + SkRect::MakeIWH(FLAGS_width, FLAGS_height), + SkMatrix::kCenter_ScaleToFit)); + + canvas->clear(SK_ColorTRANSPARENT); + anim->render(canvas); + + auto png_data = fSurface->makeImageSnapshot()->encodeToData(); + if (!png_data) { + SkDebugf("Failed to encode frame!\n"); + return false; + } + + return stream->write(png_data->data(), png_data->size()); + } + +private: + const sk_sp<SkSurface> fSurface; + + using INHERITED = Sink; +}; + +class SKPSink final : public Sink { +public: + SKPSink() : INHERITED("skp") {} + + bool saveFrame(const sk_sp<skottie::Animation>& anim, SkFILEWStream* stream) const override { + SkPictureRecorder recorder; + + auto canvas = recorder.beginRecording(FLAGS_width, FLAGS_height); + canvas->concat(SkMatrix::MakeRectToRect(SkRect::MakeSize(anim->size()), + SkRect::MakeIWH(FLAGS_width, FLAGS_height), + SkMatrix::kCenter_ScaleToFit)); + anim->render(canvas); + recorder.finishRecordingAsPicture()->serialize(stream); + + return true; + } + +private: + const sk_sp<SkSurface> fSurface; + + using INHERITED = Sink; +}; + +} // namespace + int main(int argc, char** argv) { -#if defined(SK_ENABLE_SKOTTIE) SkCommandLineFlags::Parse(argc, argv); SkAutoGraphics ag; @@ -46,23 +141,22 @@ int main(int argc, char** argv) { return 1; } - auto anim = skottie::Animation::MakeFromFile(FLAGS_input[0]); - if (!anim) { - SkDebugf("Could not load animation: '%s'.\n", FLAGS_input[0]); + std::unique_ptr<Sink> sink; + if (0 == strcmp(FLAGS_format[0], "png")) { + sink = skstd::make_unique<PNGSink>(); + } else if (0 == strcmp(FLAGS_format[0], "skp")) { + sink = skstd::make_unique<SKPSink>(); + } else { + SkDebugf("Unknown format: %s\n", FLAGS_format[0]); return 1; } - auto surface = SkSurface::MakeRasterN32Premul(FLAGS_width, FLAGS_height); - if (!surface) { - SkDebugf("Could not allocate a %d x %d buffer.\n", FLAGS_width, FLAGS_height); + auto anim = skottie::Animation::MakeFromFile(FLAGS_input[0]); + if (!anim) { + SkDebugf("Could not load animation: '%s'.\n", FLAGS_input[0]); return 1; } - auto* canvas = surface->getCanvas(); - canvas->concat(SkMatrix::MakeRectToRect(SkRect::MakeSize(anim->size()), - SkRect::MakeIWH(FLAGS_width, FLAGS_height), - SkMatrix::kCenter_ScaleToFit)); - static constexpr double kMaxFrames = 10000; const auto t0 = SkTPin(FLAGS_t0, 0.0, 1.0), t1 = SkTPin(FLAGS_t1, t0, 1.0), @@ -70,31 +164,9 @@ int main(int argc, char** argv) { size_t frame_index = 0; for (auto t = t0; t <= t1; t += advance) { - canvas->clear(SK_ColorTRANSPARENT); - anim->seek(t); - anim->render(canvas); - - auto png_data = surface->makeImageSnapshot()->encodeToData(); - if (!png_data) { - SkDebugf("Failed to encode frame #%lu\n", frame_index); - return 1; - } - - const auto frame_file = SkStringPrintf("0%06d.png", frame_index++); - - SkFILEWStream wstream(SkOSPath::Join(FLAGS_writePath[0], frame_file.c_str()).c_str()); - if (!wstream.isValid()) { - SkDebugf("Could not open '%s/%s' for writing.\n", - FLAGS_writePath[0], frame_file.c_str()); - return 1; - } - - wstream.write(png_data->data(), png_data->size()); + sink->handleFrame(anim, frame_index++); } -#else - SkDebugf("This tool requires Skottie support.\n"); -#endif return 0; } |