• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "gm/gm.h"
9 #include "include/core/SkBitmap.h"
10 #include "include/core/SkBlendMode.h"
11 #include "include/core/SkCanvas.h"
12 #include "include/core/SkColor.h"
13 #include "include/core/SkColorFilter.h"
14 #include "include/core/SkImage.h"
15 #include "include/core/SkImageFilter.h"
16 #include "include/core/SkPaint.h"
17 #include "include/core/SkPoint.h"
18 #include "include/core/SkRect.h"
19 #include "include/core/SkRefCnt.h"
20 #include "include/core/SkScalar.h"
21 #include "include/core/SkSize.h"
22 #include "include/core/SkString.h"
23 #include "include/effects/SkImageFilters.h"
24 #include "tools/ToolUtils.h"
25 
26 #include <utility>
27 
28 class ImageFiltersGraphGM : public skiagm::GM {
29 public:
ImageFiltersGraphGM()30     ImageFiltersGraphGM() {}
31 
32 protected:
33 
onShortName()34     SkString onShortName() override {
35         return SkString("imagefiltersgraph");
36     }
37 
onISize()38     SkISize onISize() override { return SkISize::Make(600, 150); }
39 
onOnceBeforeDraw()40     void onOnceBeforeDraw() override {
41         fImage = ToolUtils::create_string_image(100, 100, SK_ColorWHITE, 20, 70, 96, "e");
42     }
43 
onDraw(SkCanvas * canvas)44     void onDraw(SkCanvas* canvas) override {
45         canvas->clear(SK_ColorBLACK);
46         {
47             sk_sp<SkImageFilter> bitmapSource(SkImageFilters::Image(fImage));
48             sk_sp<SkColorFilter> cf(SkColorFilters::Blend(SK_ColorRED,
49                                                                   SkBlendMode::kSrcIn));
50             sk_sp<SkImageFilter> blur(SkImageFilters::Blur(4.0f, 4.0f, std::move(bitmapSource)));
51             sk_sp<SkImageFilter> erode(SkImageFilters::Erode(4, 4, blur));
52             sk_sp<SkImageFilter> color(SkImageFilters::ColorFilter(std::move(cf),
53                                                                       std::move(erode)));
54             sk_sp<SkImageFilter> merge(SkImageFilters::Merge(blur, color));
55 
56             SkPaint paint;
57             paint.setImageFilter(std::move(merge));
58             canvas->drawPaint(paint);
59             canvas->translate(SkIntToScalar(100), 0);
60         }
61         {
62             sk_sp<SkImageFilter> morph(SkImageFilters::Dilate(5, 5, nullptr));
63 
64             float matrix[20] = { 1, 0, 0, 0, 0,
65                                  0, 1, 0, 0, 0,
66                                  0, 0, 1, 0, 0,
67                                  0, 0, 0, 0.5f, 0 };
68 
69             sk_sp<SkColorFilter> matrixFilter(SkColorFilters::Matrix(matrix));
70             sk_sp<SkImageFilter> colorMorph(SkImageFilters::ColorFilter(std::move(matrixFilter),
71                                                                            std::move(morph)));
72             SkPaint paint;
73             paint.setImageFilter(SkImageFilters::Blend(SkBlendMode::kSrcOver,
74                                                        std::move(colorMorph)));
75 
76             DrawClippedImage(canvas, fImage.get(), paint);
77             canvas->translate(SkIntToScalar(100), 0);
78         }
79         {
80             float matrix[20] = { 1, 0, 0, 0, 0,
81                                  0, 1, 0, 0, 0,
82                                  0, 0, 1, 0, 0,
83                                  0, 0, 0, 0.5f, 0 };
84             sk_sp<SkColorFilter> matrixCF(SkColorFilters::Matrix(matrix));
85             sk_sp<SkImageFilter> matrixFilter(SkImageFilters::ColorFilter(std::move(matrixCF),
86                                                                              nullptr));
87             sk_sp<SkImageFilter> offsetFilter(SkImageFilters::Offset(10.0f, 10.f, matrixFilter));
88 
89             SkPaint paint;
90             paint.setImageFilter(SkImageFilters::Arithmetic(
91                     0, 1, 1, 0, true, std::move(matrixFilter), std::move(offsetFilter), nullptr));
92 
93             DrawClippedImage(canvas, fImage.get(), paint);
94             canvas->translate(SkIntToScalar(100), 0);
95         }
96         {
97             sk_sp<SkImageFilter> blur(SkImageFilters::Blur(10, 10, nullptr));
98 
99             SkIRect cropRect = SkIRect::MakeWH(95, 100);
100             SkPaint paint;
101             paint.setImageFilter(
102                 SkImageFilters::Blend(SkBlendMode::kSrcIn, std::move(blur), nullptr, &cropRect));
103             DrawClippedImage(canvas, fImage.get(), paint);
104             canvas->translate(SkIntToScalar(100), 0);
105         }
106         {
107             // Dilate -> matrix convolution.
108             // This tests that a filter using asFragmentProcessor (matrix
109             // convolution) correctly handles a non-zero source offset
110             // (supplied by the dilate).
111             sk_sp<SkImageFilter> dilate(SkImageFilters::Dilate(5, 5, nullptr));
112 
113             SkScalar kernel[9] = { -1, -1, -1,
114                                    -1,  7, -1,
115                                    -1, -1, -1 };
116             SkISize kernelSize = SkISize::Make(3, 3);
117             SkScalar gain = 1.0f, bias = 0;
118             SkIPoint kernelOffset = SkIPoint::Make(1, 1);
119             bool convolveAlpha = false;
120             sk_sp<SkImageFilter> convolve(SkImageFilters::MatrixConvolution(
121                     kernelSize, kernel, gain, bias, kernelOffset, SkTileMode::kClamp, convolveAlpha,
122                     std::move(dilate)));
123 
124             SkPaint paint;
125             paint.setImageFilter(std::move(convolve));
126             DrawClippedImage(canvas, fImage.get(), paint);
127             canvas->translate(SkIntToScalar(100), 0);
128         }
129         {
130             // Test that crop offsets are absolute, not relative to the parent's crop rect.
131             sk_sp<SkColorFilter> cf1(SkColorFilters::Blend(SK_ColorBLUE, SkBlendMode::kSrcIn));
132             sk_sp<SkColorFilter> cf2(SkColorFilters::Blend(SK_ColorGREEN, SkBlendMode::kSrcIn));
133             SkIRect outerRect = SkIRect::MakeXYWH(10, 10, 80, 80);
134             SkIRect innerRect= SkIRect::MakeXYWH(20, 20, 60, 60);
135             sk_sp<SkImageFilter> color1(SkImageFilters::ColorFilter(
136                     std::move(cf1), nullptr, &outerRect));
137             sk_sp<SkImageFilter> color2(SkImageFilters::ColorFilter(
138                     std::move(cf2), std::move(color1),  &innerRect));
139 
140             SkPaint paint;
141             paint.setImageFilter(std::move(color2));
142             paint.setColor(SK_ColorRED);
143             canvas->drawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint);
144             canvas->translate(SkIntToScalar(100), 0);
145         }
146     }
147 
148 private:
DrawClippedImage(SkCanvas * canvas,const SkImage * image,const SkPaint & paint)149     static void DrawClippedImage(SkCanvas* canvas, const SkImage* image, const SkPaint& paint) {
150         canvas->save();
151         canvas->clipIRect(image->bounds());
152         canvas->drawImage(image, 0, 0, SkSamplingOptions(), &paint);
153         canvas->restore();
154     }
155 
156     sk_sp<SkImage> fImage;
157 
158     using INHERITED = GM;
159 };
160 
161 ///////////////////////////////////////////////////////////////////////////////
162 
163 DEF_GM(return new ImageFiltersGraphGM;)
164