Skia
2D Graphics Library
SkImageFilters.h
Go to the documentation of this file.
1 /*
2  * Copyright 2019 Google LLC
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 #ifndef SkImageFilters_DEFINED
9 #define SkImageFilters_DEFINED
10 
11 #include "include/core/SkColor.h"
12 #include "include/core/SkImage.h"
14 #include "include/core/SkPicture.h"
15 #include "include/core/SkRect.h"
16 #include "include/core/SkRefCnt.h"
17 #include "include/core/SkScalar.h"
18 #include "include/core/SkShader.h"
20 #include "include/core/SkTypes.h"
21 
22 #include <cstddef>
23 #include <optional>
24 #include <string_view>
25 #include <utility>
26 
27 class SkBlender;
28 class SkColorFilter;
29 class SkMatrix;
31 enum class SkBlendMode;
32 struct SkIPoint;
33 struct SkISize;
34 struct SkPoint3;
35 struct SkSamplingOptions;
36 
37 // A set of factory functions providing useful SkImageFilter effects. For image filters that take an
38 // input filter, providing nullptr means it will automatically use the dynamic source image. This
39 // source depends on how the filter is applied, but is either the contents of a saved layer when
40 // drawing with SkCanvas, or an explicit SkImage if using one of the SkImages::MakeWithFilter
41 // factories.
42 class SK_API SkImageFilters {
43 public:
44  // This is just a convenience type to allow passing SkIRects, SkRects, and optional pointers
45  // to those types as a crop rect for the image filter factories. It's not intended to be used
46  // directly.
47  struct CropRect : public std::optional<SkRect> {
48  CropRect() {}
49  // Intentionally not explicit so callers don't have to use this type but can use SkIRect or
50  // SkRect as desired.
51  CropRect(const SkIRect& crop) : std::optional<SkRect>(SkRect::Make(crop)) {}
52  CropRect(const SkRect& crop) : std::optional<SkRect>(crop) {}
53  CropRect(const std::optional<SkRect>& crop) : std::optional<SkRect>(crop) {}
54  CropRect(const std::nullopt_t&) : std::optional<SkRect>() {}
55 
56  // Backwards compatibility for when the APIs used to explicitly accept "const SkRect*"
57  CropRect(std::nullptr_t) {}
58  CropRect(const SkIRect* optionalCrop) {
59  if (optionalCrop) {
60  *this = SkRect::Make(*optionalCrop);
61  }
62  }
63  CropRect(const SkRect* optionalCrop) {
64  if (optionalCrop) {
65  *this = *optionalCrop;
66  }
67  }
68 
69  // std::optional doesn't define == when comparing to another optional...
70  bool operator==(const CropRect& o) const {
71  return this->has_value() == o.has_value() &&
72  (!this->has_value() || this->value() == *o);
73  }
74  };
75 
87  bool enforcePMColor, sk_sp<SkImageFilter> background,
88  sk_sp<SkImageFilter> foreground,
89  const CropRect& cropRect = {});
90 
99  sk_sp<SkImageFilter> foreground = nullptr,
100  const CropRect& cropRect = {});
101 
110  sk_sp<SkImageFilter> foreground = nullptr,
111  const CropRect& cropRect = {});
112 
123  static sk_sp<SkImageFilter> Blur(SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode,
124  sk_sp<SkImageFilter> input, const CropRect& cropRect = {});
125  // As above, but defaults to the decal tile mode.
127  const CropRect& cropRect = {}) {
128  return Blur(sigmaX, sigmaY, SkTileMode::kDecal, std::move(input), cropRect);
129  }
130 
138  const CropRect& cropRect = {});
139 
147 
162  static sk_sp<SkImageFilter> Crop(const SkRect& rect,
163  SkTileMode tileMode,
164  sk_sp<SkImageFilter> input);
166  return Crop(rect, SkTileMode::kDecal, std::move(input));
167  }
168 
183  SkColorChannel yChannelSelector,
184  SkScalar scale, sk_sp<SkImageFilter> displacement,
185  sk_sp<SkImageFilter> color,
186  const CropRect& cropRect = {});
187 
200  SkScalar sigmaX, SkScalar sigmaY,
201  SkColor color, sk_sp<SkImageFilter> input,
202  const CropRect& cropRect = {});
216  SkScalar sigmaX, SkScalar sigmaY,
217  SkColor color, sk_sp<SkImageFilter> input,
218  const CropRect& cropRect = {});
219 
224 
235  static sk_sp<SkImageFilter> Image(sk_sp<SkImage> image, const SkRect& srcRect,
236  const SkRect& dstRect, const SkSamplingOptions& sampling);
237 
247  if (image) {
248  SkRect r = SkRect::Make(image->bounds());
249  return Image(std::move(image), r, r, sampling);
250  } else {
251  return nullptr;
252  }
253  }
254 
265  static sk_sp<SkImageFilter> Magnifier(const SkRect& lensBounds,
266  SkScalar zoomAmount,
267  SkScalar inset,
268  const SkSamplingOptions& sampling,
269  sk_sp<SkImageFilter> input,
270  const CropRect& cropRect = {});
271 
291  const SkScalar kernel[], SkScalar gain,
292  SkScalar bias, const SkIPoint& kernelOffset,
293  SkTileMode tileMode, bool convolveAlpha,
294  sk_sp<SkImageFilter> input,
295  const CropRect& cropRect = {});
296 
306  const SkSamplingOptions& sampling,
307  sk_sp<SkImageFilter> input);
308 
317  static sk_sp<SkImageFilter> Merge(sk_sp<SkImageFilter>* const filters, int count,
318  const CropRect& cropRect = {});
326  const CropRect& cropRect = {}) {
327  sk_sp<SkImageFilter> array[] = { std::move(first), std::move(second) };
328  return Merge(array, 2, cropRect);
329  }
330 
339  const CropRect& cropRect = {});
340 
350  static sk_sp<SkImageFilter> Picture(sk_sp<SkPicture> pic, const SkRect& targetRect);
351  // As above, but uses SkPicture::cullRect for the drawing region.
353  SkRect target = pic ? pic->cullRect() : SkRect::MakeEmpty();
354  return Picture(std::move(pic), target);
355  }
356 
377  std::string_view childShaderName,
378  sk_sp<SkImageFilter> input) {
379  return RuntimeShader(builder, /*sampleRadius=*/0.f, childShaderName, std::move(input));
380  }
381 
394  SkScalar sampleRadius,
395  std::string_view childShaderName,
396  sk_sp<SkImageFilter> input);
397 
416  std::string_view childShaderNames[],
417  const sk_sp<SkImageFilter> inputs[],
418  int inputCount) {
419  return RuntimeShader(builder, /*maxSampleRadius=*/0.f, childShaderNames,
420  inputs, inputCount);
421  }
422 
433  SkScalar maxSampleRadius,
434  std::string_view childShaderNames[],
435  const sk_sp<SkImageFilter> inputs[],
436  int inputCount);
437 
438  enum class Dither : bool {
439  kNo = false,
440  kYes = true
441  };
442 
456  static sk_sp<SkImageFilter> Shader(sk_sp<SkShader> shader, const CropRect& cropRect = {}) {
457  return Shader(std::move(shader), Dither::kNo, cropRect);
458  }
460  const CropRect& cropRect = {});
461 
468  static sk_sp<SkImageFilter> Tile(const SkRect& src, const SkRect& dst,
469  sk_sp<SkImageFilter> input);
470 
471  // Morphology filter effects
472 
481  static sk_sp<SkImageFilter> Dilate(SkScalar radiusX, SkScalar radiusY,
482  sk_sp<SkImageFilter> input,
483  const CropRect& cropRect = {});
484 
493  static sk_sp<SkImageFilter> Erode(SkScalar radiusX, SkScalar radiusY,
494  sk_sp<SkImageFilter> input,
495  const CropRect& cropRect = {});
496 
497  // Lighting filter effects
498 
511  static sk_sp<SkImageFilter> DistantLitDiffuse(const SkPoint3& direction, SkColor lightColor,
512  SkScalar surfaceScale, SkScalar kd,
513  sk_sp<SkImageFilter> input,
514  const CropRect& cropRect = {});
527  static sk_sp<SkImageFilter> PointLitDiffuse(const SkPoint3& location, SkColor lightColor,
528  SkScalar surfaceScale, SkScalar kd,
529  sk_sp<SkImageFilter> input,
530  const CropRect& cropRect = {});
547  static sk_sp<SkImageFilter> SpotLitDiffuse(const SkPoint3& location, const SkPoint3& target,
548  SkScalar falloffExponent, SkScalar cutoffAngle,
549  SkColor lightColor, SkScalar surfaceScale,
550  SkScalar kd, sk_sp<SkImageFilter> input,
551  const CropRect& cropRect = {});
552 
566  static sk_sp<SkImageFilter> DistantLitSpecular(const SkPoint3& direction, SkColor lightColor,
567  SkScalar surfaceScale, SkScalar ks,
568  SkScalar shininess, sk_sp<SkImageFilter> input,
569  const CropRect& cropRect = {});
583  static sk_sp<SkImageFilter> PointLitSpecular(const SkPoint3& location, SkColor lightColor,
584  SkScalar surfaceScale, SkScalar ks,
585  SkScalar shininess, sk_sp<SkImageFilter> input,
586  const CropRect& cropRect = {});
604  static sk_sp<SkImageFilter> SpotLitSpecular(const SkPoint3& location, const SkPoint3& target,
605  SkScalar falloffExponent, SkScalar cutoffAngle,
606  SkColor lightColor, SkScalar surfaceScale,
607  SkScalar ks, SkScalar shininess,
608  sk_sp<SkImageFilter> input,
609  const CropRect& cropRect = {});
610 
611 private:
612  SkImageFilters() = delete;
613 };
614 
615 #endif // SkImageFilters_DEFINED
SkBlendMode
Blends are operators that take in two colors (source, destination) and return a new color.
Definition: SkBlendMode.h:38
Types, consts, functions, and macros for colors.
uint32_t SkColor
32-bit ARGB color value, unpremultiplied.
Definition: SkColor.h:37
SkColorChannel
Describes different color channels one can manipulate.
Definition: SkColor.h:228
@ kYes
Do pre-clip the geometry before applying the (perspective) matrix.
@ kNo
Don't pre-clip the geometry before applying the (perspective) matrix.
float SkScalar
Definition: SkScalar.h:14
SkTileMode
Definition: SkTileMode.h:13
@ kDecal
Only draw within the original domain, return transparent-black everywhere else.
SkBlender represents a custom blend function in the Skia pipeline.
Definition: SkBlender.h:19
ColorFilters are optional objects in the drawing pipeline.
Definition: SkColorFilter.h:35
Definition: SkImageFilters.h:42
static sk_sp< SkImageFilter > PointLitDiffuse(const SkPoint3 &location, SkColor lightColor, SkScalar surfaceScale, SkScalar kd, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that calculates the diffuse illumination from a point light source,...
Dither
Definition: SkImageFilters.h:438
static sk_sp< SkImageFilter > Crop(const SkRect &rect, SkTileMode tileMode, sk_sp< SkImageFilter > input)
Create a filter that applies a crop to the result of the 'input' filter.
static sk_sp< SkImageFilter > SpotLitDiffuse(const SkPoint3 &location, const SkPoint3 &target, SkScalar falloffExponent, SkScalar cutoffAngle, SkColor lightColor, SkScalar surfaceScale, SkScalar kd, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that calculates the diffuse illumination from a spot light source,...
static sk_sp< SkImageFilter > Merge(sk_sp< SkImageFilter > *const filters, int count, const CropRect &cropRect={})
Create a filter that merges the 'count' filters together by drawing their results in order with src-o...
static sk_sp< SkImageFilter > Shader(sk_sp< SkShader > shader, const CropRect &cropRect={})
Create a filter that fills the output with the per-pixel evaluation of the SkShader.
Definition: SkImageFilters.h:456
static sk_sp< SkImageFilter > Picture(sk_sp< SkPicture > pic)
Definition: SkImageFilters.h:352
static sk_sp< SkImageFilter > Magnifier(const SkRect &lensBounds, SkScalar zoomAmount, SkScalar inset, const SkSamplingOptions &sampling, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that fills 'lensBounds' with a magnification of the input.
static sk_sp< SkImageFilter > Empty()
Create a filter that always produces transparent black.
static sk_sp< SkImageFilter > Blend(SkBlendMode mode, sk_sp< SkImageFilter > background, sk_sp< SkImageFilter > foreground=nullptr, const CropRect &cropRect={})
This filter takes an SkBlendMode and uses it to composite the two filters together.
static sk_sp< SkImageFilter > Blur(SkScalar sigmaX, SkScalar sigmaY, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Definition: SkImageFilters.h:126
static sk_sp< SkImageFilter > MatrixTransform(const SkMatrix &matrix, const SkSamplingOptions &sampling, sk_sp< SkImageFilter > input)
Create a filter that transforms the input image by 'matrix'.
static sk_sp< SkImageFilter > DropShadowOnly(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor color, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that renders a drop shadow, in exactly the same manner as ::DropShadow,...
static sk_sp< SkImageFilter > Crop(const SkRect &rect, sk_sp< SkImageFilter > input)
Definition: SkImageFilters.h:165
static sk_sp< SkImageFilter > Blur(SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that blurs its input by the separate X and Y sigmas.
static sk_sp< SkImageFilter > DisplacementMap(SkColorChannel xChannelSelector, SkColorChannel yChannelSelector, SkScalar scale, sk_sp< SkImageFilter > displacement, sk_sp< SkImageFilter > color, const CropRect &cropRect={})
Create a filter that moves each pixel in its color input based on an (x,y) vector encoded in its disp...
static sk_sp< SkImageFilter > Image(sk_sp< SkImage > image, const SkRect &srcRect, const SkRect &dstRect, const SkSamplingOptions &sampling)
Create a filter that draws the 'srcRect' portion of image into 'dstRect' using the given filter quali...
static sk_sp< SkImageFilter > Erode(SkScalar radiusX, SkScalar radiusY, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that erodes each input pixel's channel values to the minimum channel value within the...
static sk_sp< SkImageFilter > Tile(const SkRect &src, const SkRect &dst, sk_sp< SkImageFilter > input)
Create a tile image filter.
static sk_sp< SkImageFilter > ColorFilter(sk_sp< SkColorFilter > cf, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that applies the color filter to the input filter results.
static sk_sp< SkImageFilter > SpotLitSpecular(const SkPoint3 &location, const SkPoint3 &target, SkScalar falloffExponent, SkScalar cutoffAngle, SkColor lightColor, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that calculates the specular illumination from a spot light source,...
static sk_sp< SkImageFilter > MatrixConvolution(const SkISize &kernelSize, const SkScalar kernel[], SkScalar gain, SkScalar bias, const SkIPoint &kernelOffset, SkTileMode tileMode, bool convolveAlpha, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that applies an NxM image processing kernel to the input image.
static sk_sp< SkImageFilter > Shader(sk_sp< SkShader > shader, Dither dither, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Picture(sk_sp< SkPicture > pic, const SkRect &targetRect)
Create a filter that produces the SkPicture as its output, clipped to both 'targetRect' and the pictu...
static sk_sp< SkImageFilter > RuntimeShader(const SkRuntimeShaderBuilder &builder, std::string_view childShaderNames[], const sk_sp< SkImageFilter > inputs[], int inputCount)
Create a filter that fills the output with the per-pixel evaluation of the SkShader produced by the S...
Definition: SkImageFilters.h:415
static sk_sp< SkImageFilter > Merge(sk_sp< SkImageFilter > first, sk_sp< SkImageFilter > second, const CropRect &cropRect={})
Create a filter that merges the results of the two filters together with src-over blending.
Definition: SkImageFilters.h:325
static sk_sp< SkImageFilter > Dilate(SkScalar radiusX, SkScalar radiusY, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that dilates each input pixel's channel values to the max value within the given radi...
static sk_sp< SkImageFilter > Arithmetic(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, bool enforcePMColor, sk_sp< SkImageFilter > background, sk_sp< SkImageFilter > foreground, const CropRect &cropRect={})
Create a filter that implements a custom blend mode.
static sk_sp< SkImageFilter > RuntimeShader(const SkRuntimeShaderBuilder &builder, std::string_view childShaderName, sk_sp< SkImageFilter > input)
Create a filter that fills the output with the per-pixel evaluation of the SkShader produced by the S...
Definition: SkImageFilters.h:376
static sk_sp< SkImageFilter > Blend(sk_sp< SkBlender > blender, sk_sp< SkImageFilter > background, sk_sp< SkImageFilter > foreground=nullptr, const CropRect &cropRect={})
This filter takes an SkBlendMode and uses it to composite the two filters together.
static sk_sp< SkImageFilter > DropShadow(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor color, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that draws a drop shadow under the input content.
static sk_sp< SkImageFilter > RuntimeShader(const SkRuntimeShaderBuilder &builder, SkScalar maxSampleRadius, std::string_view childShaderNames[], const sk_sp< SkImageFilter > inputs[], int inputCount)
As above, but 'maxSampleRadius' defines the sampling limit on coordinates provided to all child shade...
static sk_sp< SkImageFilter > DistantLitDiffuse(const SkPoint3 &direction, SkColor lightColor, SkScalar surfaceScale, SkScalar kd, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that calculates the diffuse illumination from a distant light source,...
static sk_sp< SkImageFilter > Image(sk_sp< SkImage > image, const SkSamplingOptions &sampling)
Create a filter that draws the image using the given sampling.
Definition: SkImageFilters.h:246
static sk_sp< SkImageFilter > Offset(SkScalar dx, SkScalar dy, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that offsets the input filter by the given vector.
static sk_sp< SkImageFilter > PointLitSpecular(const SkPoint3 &location, SkColor lightColor, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that calculates the specular illumination from a point light source,...
static sk_sp< SkImageFilter > DistantLitSpecular(const SkPoint3 &direction, SkColor lightColor, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
Create a filter that calculates the specular illumination from a distant light source,...
static sk_sp< SkImageFilter > RuntimeShader(const SkRuntimeShaderBuilder &builder, SkScalar sampleRadius, std::string_view childShaderName, sk_sp< SkImageFilter > input)
As above, but 'sampleRadius' defines the sampling radius of 'childShaderName' relative to the runtime...
static sk_sp< SkImageFilter > Compose(sk_sp< SkImageFilter > outer, sk_sp< SkImageFilter > inner)
Create a filter that composes 'inner' with 'outer', such that the results of 'inner' are treated as t...
SkIRect bounds() const
Returns SkIRect { 0, 0, width(), height() }.
Definition: SkImage.h:301
SkMatrix holds a 3x3 matrix for transforming coordinates.
Definition: SkMatrix.h:53
virtual SkRect cullRect() const =0
Returns cull SkRect for this picture, passed in when SkPicture was created.
SkRuntimeShaderBuilder is a utility to simplify creating SkShader objects from SkRuntimeEffects.
Definition: SkRuntimeEffect.h:473
sk_sp< SkDrawLooper > SK_API Make(SkColor4f color, SkColorSpace *cs, SkScalar sigma, SkScalar dx, SkScalar dy)
SkIRect holds four 32-bit integer coordinates describing the upper and lower bounds of a rectangle.
Definition: SkRect.h:32
Definition: SkSize.h:15
Definition: SkImageFilters.h:47
CropRect(const SkIRect &crop)
Definition: SkImageFilters.h:51
CropRect(const std::nullopt_t &)
Definition: SkImageFilters.h:54
CropRect(const SkRect *optionalCrop)
Definition: SkImageFilters.h:63
CropRect(const SkIRect *optionalCrop)
Definition: SkImageFilters.h:58
CropRect(std::nullptr_t)
Definition: SkImageFilters.h:57
bool operator==(const CropRect &o) const
Definition: SkImageFilters.h:70
CropRect()
Definition: SkImageFilters.h:48
CropRect(const std::optional< SkRect > &crop)
Definition: SkImageFilters.h:53
CropRect(const SkRect &crop)
Definition: SkImageFilters.h:52
Definition: SkPoint3.h:14
SkRect holds four float coordinates describing the upper and lower bounds of a rectangle.
Definition: SkRect.h:582
static SkRect Make(const SkISize &size)
Returns constructed SkIRect set to (0, 0, size.width(), size.height()).
Definition: SkRect.h:669
static constexpr SkRect MakeEmpty()
Returns constructed SkRect set to (0, 0, 0, 0).
Definition: SkRect.h:595
Definition: SkSamplingOptions.h:58