aboutsummaryrefslogtreecommitdiffhomepage
path: root/samplecode
diff options
context:
space:
mode:
authorGravatar Leon Scroggins III <scroggo@google.com>2018-01-12 11:24:30 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-01-12 19:36:11 +0000
commit7a10b332a37dab94b1c59685714f6d8c28fc84b9 (patch)
tree45a7847d658bd1d9ff3e6499633c512933c0b1e3 /samplecode
parent65fa8ca85ef146340ddea61bb08c182df499ca62 (diff)
Add an SkDrawable for animated images (e.g. GIF)
Bug: b/63909536 SkAnimatedImage is a simple drawable for animating a GIF. Thread-safety is left up to the client. At most two bitmaps are stored in the drawable; one for the current frame and one for a frame that may need to be restored. The backup frame prevents some cases where we would otherwise have to re-decode from the beginning of the image. The API lets the client set the time value, and decodes to match that time. TODO: - Callback for when the animation is complete - Ability to use SkAndroidCodec - Modify the loop count (or leave that up to client?) - Better and/or client-specific caching Other changes: - Add a sample which animates a GIF - Reenable SK_CODEC_PRINTF for debug builds and Android Change-Id: I945ffbccdb6008f2a05ed4d9b2af869a261fb300 Reviewed-on: https://skia-review.googlesource.com/93420 Reviewed-by: Derek Sollenberger <djsollen@google.com> Commit-Queue: Leon Scroggins <scroggo@google.com>
Diffstat (limited to 'samplecode')
-rw-r--r--samplecode/SampleAnimatedImage.cpp130
1 files changed, 130 insertions, 0 deletions
diff --git a/samplecode/SampleAnimatedImage.cpp b/samplecode/SampleAnimatedImage.cpp
new file mode 100644
index 0000000000..96e53b8e4e
--- /dev/null
+++ b/samplecode/SampleAnimatedImage.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkAnimatedImage.h"
+#include "SkAnimTimer.h"
+#include "SkCanvas.h"
+#include "SkCodec.h"
+#include "SkPaint.h"
+#include "SkPictureRecorder.h"
+#include "SkRect.h"
+#include "SkScalar.h"
+#include "SkString.h"
+
+#include "SampleCode.h"
+#include "Resources.h"
+
+static constexpr char kPauseKey = 'p';
+static constexpr char kResetKey = 'r';
+
+class SampleAnimatedImage : public SampleView {
+public:
+ SampleAnimatedImage()
+ : INHERITED()
+ , fRunning(false)
+ , fYOffset(0)
+ {}
+
+protected:
+ void onDrawBackground(SkCanvas* canvas) override {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ constexpr SkScalar kTextSize = 20;
+ paint.setTextSize(kTextSize);
+
+ SkString str = SkStringPrintf("Press '%c' to start/pause; '%c' to reset.",
+ kPauseKey, kResetKey);
+ const char* text = str.c_str();
+ SkRect bounds;
+ paint.measureText(text, strlen(text), &bounds);
+ fYOffset = bounds.height();
+
+ canvas->drawText(text, strlen(text), 5, fYOffset, paint);
+ fYOffset *= 2;
+ }
+
+ void onDrawContent(SkCanvas* canvas) override {
+ if (!fImage) {
+ return;
+ }
+
+ canvas->translate(0, fYOffset);
+
+ canvas->drawDrawable(fImage.get());
+ canvas->drawDrawable(fDrawable.get(), fImage->getBounds().width(), 0);
+ }
+
+ bool onAnimate(const SkAnimTimer& animTimer) override {
+ if (!fImage) {
+ return false;
+ }
+
+ fImage->update(animTimer.msec());
+ return true;
+ }
+
+ void onOnceBeforeDraw() override {
+ sk_sp<SkData> file(GetResourceAsData("images/alphabetAnim.gif"));
+ std::unique_ptr<SkCodec> codec(SkCodec::MakeFromData(file));
+ if (!codec) {
+ return;
+ }
+
+ fImage = SkAnimatedImage::MakeFromCodec(std::move(codec));
+ if (!fImage) {
+ return;
+ }
+
+ SkPictureRecorder recorder;
+ auto canvas = recorder.beginRecording(fImage->getBounds());
+ canvas->drawDrawable(fImage.get());
+ fDrawable = recorder.finishRecordingAsDrawable();
+ }
+
+ bool onQuery(SkEvent* evt) override {
+ if (SampleCode::TitleQ(*evt)) {
+ SampleCode::TitleR(evt, "AnimatedImage");
+ return true;
+ }
+
+ SkUnichar uni;
+ if (fImage && SampleCode::CharQ(*evt, &uni)) {
+ switch (uni) {
+ case kPauseKey:
+ if (fRunning) {
+ fImage->stop();
+ fRunning = false;
+ } else {
+ fImage->start();
+ fRunning = true;
+ }
+ return true;
+ case kResetKey:
+ fImage->reset();
+ return true;
+ default:
+ break;
+ }
+ }
+ return this->INHERITED::onQuery(evt);
+ }
+
+private:
+ sk_sp<SkAnimatedImage> fImage;
+ sk_sp<SkDrawable> fDrawable;
+ bool fRunning;
+ SkScalar fYOffset;
+ typedef SampleView INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() {
+ return new SampleAnimatedImage;
+}
+
+static SkViewRegister reg(MyFactory);