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