aboutsummaryrefslogtreecommitdiffhomepage
path: root/modules
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2018-07-13 15:47:27 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-07-15 02:52:38 +0000
commit0c604ed06b71dacaa7d685c0a833b8d07c2729b5 (patch)
treea494ae990a5ab318c35642a0b7ff4daf4ec1b2b5 /modules
parent6f6fdf91f66d2d98c099d832fd19d0c451c107b2 (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.cpp144
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;
}