Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(496)

Unified Diff: gm/image.cpp

Issue 1396323007: API to support native scaling by image-generator (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: mark test image as opaque, so jpeg has a chance of encoding it Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | include/core/SkImageGenerator.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gm/image.cpp
diff --git a/gm/image.cpp b/gm/image.cpp
index 991b4014f02aa3bfff0a2a3126a29f5210a21591..ac72f63b36f96dc2ab271778578d9e31a588b35e 100644
--- a/gm/image.cpp
+++ b/gm/image.cpp
@@ -240,33 +240,33 @@ static void draw_contents(SkCanvas* canvas) {
canvas->drawCircle(50, 50, 35, paint);
}
-static SkImage* make_raster(const SkImageInfo& info, GrContext*) {
+static SkImage* make_raster(const SkImageInfo& info, GrContext*, void (*draw)(SkCanvas*)) {
SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
- draw_contents(surface->getCanvas());
+ draw(surface->getCanvas());
return surface->newImageSnapshot();
}
-static SkImage* make_picture(const SkImageInfo& info, GrContext*) {
+static SkImage* make_picture(const SkImageInfo& info, GrContext*, void (*draw)(SkCanvas*)) {
SkPictureRecorder recorder;
- draw_contents(recorder.beginRecording(SkRect::MakeIWH(info.width(), info.height())));
+ draw(recorder.beginRecording(SkRect::MakeIWH(info.width(), info.height())));
SkAutoTUnref<SkPicture> pict(recorder.endRecording());
return SkImage::NewFromPicture(pict, info.dimensions(), nullptr, nullptr);
}
-static SkImage* make_codec(const SkImageInfo& info, GrContext*) {
- SkAutoTUnref<SkImage> image(make_raster(info, nullptr));
+static SkImage* make_codec(const SkImageInfo& info, GrContext*, void (*draw)(SkCanvas*)) {
+ SkAutoTUnref<SkImage> image(make_raster(info, nullptr, draw));
SkAutoTUnref<SkData> data(image->encode());
return SkImage::NewFromEncoded(data);
}
-static SkImage* make_gpu(const SkImageInfo& info, GrContext* ctx) {
+static SkImage* make_gpu(const SkImageInfo& info, GrContext* ctx, void (*draw)(SkCanvas*)) {
if (!ctx) { return nullptr; }
SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted, info));
- draw_contents(surface->getCanvas());
+ draw(surface->getCanvas());
return surface->newImageSnapshot();
}
-typedef SkImage* (*ImageMakerProc)(const SkImageInfo&, GrContext*);
+typedef SkImage* (*ImageMakerProc)(const SkImageInfo&, GrContext*, void (*)(SkCanvas*));
class ScalePixelsGM : public skiagm::GM {
public:
@@ -288,7 +288,7 @@ protected:
make_codec, make_raster, make_picture, make_codec, make_gpu,
};
for (auto& proc : procs) {
- SkAutoTUnref<SkImage> image(proc(info, canvas->getGrContext()));
+ SkAutoTUnref<SkImage> image(proc(info, canvas->getGrContext(), draw_contents));
if (image) {
show_scaled_pixels(canvas, image);
}
@@ -300,3 +300,132 @@ private:
typedef skiagm::GM INHERITED;
};
DEF_GM( return new ScalePixelsGM; )
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "SkImageGenerator.h"
+
+static SkImageInfo make_info(SkImage* img) {
+ return SkImageInfo::MakeN32(img->width(), img->height(),
+ img->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
+}
+
+// Its simple, but I wonder if we should expose this formally?
+//
+class ImageGeneratorFromImage : public SkImageGenerator {
+public:
+ ImageGeneratorFromImage(SkImage* img) : INHERITED(make_info(img)), fImg(SkRef(img)) {}
+
+protected:
+ bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkPMColor ctable[],
+ int* ctableCount) override {
+ return fImg->readPixels(info, pixels, rowBytes, 0, 0);
+ }
+
+private:
+ SkAutoTUnref<SkImage> fImg;
+
+ typedef SkImageGenerator INHERITED;
+};
+
+static void draw_opaque_contents(SkCanvas* canvas) {
+ canvas->drawColor(0xFFFF8844);
+
+ SkPaint paint;
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(20);
+ canvas->drawCircle(50, 50, 35, paint);
+}
+
+static SkImageGenerator* gen_raster(const SkImageInfo& info) {
+ SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
+ draw_opaque_contents(surface->getCanvas());
+ SkAutoTUnref<SkImage> img(surface->newImageSnapshot());
+ return new ImageGeneratorFromImage(img);
+}
+
+static SkImageGenerator* gen_picture(const SkImageInfo& info) {
+ SkPictureRecorder recorder;
+ draw_opaque_contents(recorder.beginRecording(SkRect::MakeIWH(info.width(), info.height())));
+ SkAutoTUnref<SkPicture> pict(recorder.endRecording());
+ return SkImageGenerator::NewFromPicture(info.dimensions(), pict, nullptr, nullptr);
+}
+
+static SkImageGenerator* gen_png(const SkImageInfo& info) {
+ SkAutoTUnref<SkImage> image(make_raster(info, nullptr, draw_opaque_contents));
+ SkAutoTUnref<SkData> data(image->encode(SkImageEncoder::kPNG_Type, 100));
+ return SkImageGenerator::NewFromEncoded(data);
+}
+
+static SkImageGenerator* gen_jpg(const SkImageInfo& info) {
+ SkAutoTUnref<SkImage> image(make_raster(info, nullptr, draw_opaque_contents));
+ SkAutoTUnref<SkData> data(image->encode(SkImageEncoder::kJPEG_Type, 100));
+ return SkImageGenerator::NewFromEncoded(data);
+}
+
+typedef SkImageGenerator* (*GeneratorMakerProc)(const SkImageInfo&);
+
+static void show_scaled_generator(SkCanvas* canvas, SkImageGenerator* gen) {
+ const SkImageInfo genInfo = gen->getInfo();
+
+ SkAutoCanvasRestore acr(canvas, true);
+
+ SkBitmap bm;
+ bm.allocPixels(genInfo);
+ if (gen->getPixels(bm.info(), bm.getPixels(), bm.rowBytes())) {
+ canvas->drawBitmap(bm, 0, 0, nullptr);
+ }
+ canvas->translate(110, 0);
+
+ const float scales[] = { 0.75f, 0.5f, 0.25f };
+ for (auto scale : scales) {
+ SkImageGenerator::SupportedSizes sizes;
+ if (gen->computeScaledDimensions(scale, &sizes)) {
+ const SkImageInfo info = SkImageInfo::MakeN32Premul(sizes.fSizes[0].width(),
+ sizes.fSizes[0].height());
+ bm.allocPixels(info);
+ SkPixmap pmap;
+ bm.peekPixels(&pmap);
+ if (gen->generateScaledPixels(pmap)) {
+ canvas->drawBitmap(bm, 0, SkIntToScalar(genInfo.height() - info.height())/2);
+ }
+ }
+ canvas->translate(100, 0);
+ }
+}
+
+class ScaleGeneratorGM : public skiagm::GM {
+public:
+ ScaleGeneratorGM() {}
+
+protected:
+ SkString onShortName() override {
+ return SkString("scale-generator");
+ }
+
+ SkISize onISize() override {
+ return SkISize::Make(500, 500);
+ }
+
+ void onDraw(SkCanvas* canvas) override {
+ canvas->translate(10, 10);
+
+ // explicitly make it opaque, so we can test JPEG (which is only ever opaque)
+ const SkImageInfo info = SkImageInfo::MakeN32(100, 100, kOpaque_SkAlphaType);
+
+ const GeneratorMakerProc procs[] = {
+ gen_raster, gen_picture, gen_png, gen_jpg,
+ };
+ for (auto& proc : procs) {
+ SkAutoTDelete<SkImageGenerator> gen(proc(info));
+ if (gen) {
+ show_scaled_generator(canvas, gen);
+ }
+ canvas->translate(0, 120);
+ }
+ }
+
+private:
+ typedef skiagm::GM INHERITED;
+};
+DEF_GM( return new ScaleGeneratorGM; )
« no previous file with comments | « no previous file | include/core/SkImageGenerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698