imagealphathreshold.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. * Copyright 2013 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. #include "gm/gm.h"
  8. #include "include/core/SkBitmap.h"
  9. #include "include/core/SkCanvas.h"
  10. #include "include/core/SkColor.h"
  11. #include "include/core/SkColorSpace.h"
  12. #include "include/core/SkImage.h"
  13. #include "include/core/SkImageFilter.h"
  14. #include "include/core/SkImageInfo.h"
  15. #include "include/core/SkMatrix.h"
  16. #include "include/core/SkPaint.h"
  17. #include "include/core/SkRect.h"
  18. #include "include/core/SkRefCnt.h"
  19. #include "include/core/SkRegion.h"
  20. #include "include/core/SkSize.h"
  21. #include "include/core/SkString.h"
  22. #include "include/core/SkSurface.h"
  23. #include "include/effects/SkAlphaThresholdFilter.h"
  24. #include "include/effects/SkImageSource.h"
  25. #include "include/effects/SkOffsetImageFilter.h"
  26. #include "include/utils/SkRandom.h"
  27. #include "tools/ToolUtils.h"
  28. #include <utility>
  29. #define WIDTH 500
  30. #define HEIGHT 500
  31. static void draw_rects(SkCanvas* canvas) {
  32. SkPaint rectPaint;
  33. rectPaint.setColor(SK_ColorBLUE);
  34. canvas->drawRect(SkRect::MakeXYWH(0, 0, WIDTH / 2, HEIGHT / 2), rectPaint);
  35. rectPaint.setColor(0xBFFF0000);
  36. canvas->drawRect(SkRect::MakeXYWH(WIDTH / 2, 0, WIDTH / 2, HEIGHT / 2), rectPaint);
  37. rectPaint.setColor(0x3F00FF00);
  38. canvas->drawRect(SkRect::MakeXYWH(0, HEIGHT / 2, WIDTH / 2, HEIGHT / 2), rectPaint);
  39. rectPaint.setColor(SK_ColorTRANSPARENT);
  40. canvas->drawRect(SkRect::MakeXYWH(WIDTH / 2, HEIGHT / 2, WIDTH / 2, HEIGHT / 2), rectPaint);
  41. }
  42. static SkPaint create_filter_paint(SkImageFilter::CropRect* cropRect = nullptr) {
  43. SkIRect rects[2];
  44. rects[0] = SkIRect::MakeXYWH(0, 150, WIDTH, HEIGHT - 300);
  45. rects[1] = SkIRect::MakeXYWH(150, 0, WIDTH - 300, HEIGHT);
  46. SkRegion region;
  47. region.setRects(rects, 2);
  48. SkPaint paint;
  49. sk_sp<SkImageFilter> offset(SkOffsetImageFilter::Make(25, 25, nullptr));
  50. paint.setImageFilter(SkAlphaThresholdFilter::Make(region, 0.2f, 0.7f, std::move(offset), cropRect));
  51. return paint;
  52. }
  53. class ImageAlphaThresholdGM : public skiagm::GM {
  54. public:
  55. ImageAlphaThresholdGM(bool useCropRect) : fUseCropRect(useCropRect) {
  56. this->setBGColor(SK_ColorWHITE);
  57. }
  58. protected:
  59. SkString onShortName() override {
  60. if (fUseCropRect) {
  61. return SkString("imagealphathreshold_crop");
  62. }
  63. return SkString("imagealphathreshold");
  64. }
  65. SkISize onISize() override {
  66. return SkISize::Make(WIDTH, HEIGHT);
  67. }
  68. void onDraw(SkCanvas* canvas) override {
  69. SkMatrix matrix;
  70. matrix.reset();
  71. matrix.setTranslate(WIDTH * .1f, HEIGHT * .1f);
  72. matrix.postScale(.8f, .8f);
  73. canvas->concat(matrix);
  74. SkRect r = SkRect::MakeLTRB(100, 100, WIDTH - 100, HEIGHT - 100);
  75. SkImageFilter::CropRect cropRect(r);
  76. SkPaint paint = create_filter_paint(fUseCropRect ? &cropRect : nullptr);
  77. canvas->saveLayer(nullptr, &paint);
  78. draw_rects(canvas);
  79. canvas->restore();
  80. }
  81. private:
  82. bool fUseCropRect;
  83. typedef GM INHERITED;
  84. };
  85. // Create a 'width' x 'height' SkSurface that matches the colorType of 'canvas' as
  86. // best we can
  87. static sk_sp<SkSurface> make_color_matching_surface(SkCanvas* canvas, int width, int height,
  88. SkAlphaType at) {
  89. SkColorType ct = canvas->imageInfo().colorType();
  90. sk_sp<SkColorSpace> cs(canvas->imageInfo().refColorSpace());
  91. if (kUnknown_SkColorType == ct) {
  92. // For backends that aren't yet color-space aware we just fallback to N32.
  93. ct = kN32_SkColorType;
  94. cs = nullptr;
  95. } else if (SkColorTypeIsAlwaysOpaque(ct)) {
  96. at = kOpaque_SkAlphaType;
  97. }
  98. SkImageInfo info = SkImageInfo::Make(width, height, ct, at, std::move(cs));
  99. return ToolUtils::makeSurface(canvas, info);
  100. }
  101. class ImageAlphaThresholdSurfaceGM : public skiagm::GM {
  102. public:
  103. ImageAlphaThresholdSurfaceGM() {
  104. this->setBGColor(0xFFFFFFFF);
  105. }
  106. protected:
  107. SkString onShortName() override {
  108. return SkString("imagealphathreshold_surface");
  109. }
  110. SkISize onISize() override {
  111. return SkISize::Make(WIDTH, HEIGHT);
  112. }
  113. DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
  114. SkMatrix matrix;
  115. matrix.reset();
  116. matrix.setTranslate(WIDTH * .1f, HEIGHT * .1f);
  117. matrix.postScale(.8f, .8f);
  118. canvas->concat(matrix);
  119. sk_sp<SkSurface> surface(make_color_matching_surface(canvas, WIDTH, HEIGHT,
  120. kPremul_SkAlphaType));
  121. if (!surface) {
  122. *errorMsg = "make_color_matching_surface failed";
  123. return DrawResult::kFail;
  124. }
  125. surface->getCanvas()->clear(SK_ColorTRANSPARENT);
  126. draw_rects(surface->getCanvas());
  127. SkPaint paint = create_filter_paint();
  128. canvas->clipRect(SkRect::MakeLTRB(100, 100, WIDTH - 100, HEIGHT - 100));
  129. canvas->drawImage(surface->makeImageSnapshot().get(), 0, 0, &paint);
  130. return DrawResult::kOk;
  131. }
  132. private:
  133. typedef skiagm::GM INHERITED;
  134. };
  135. //////////////////////////////////////////////////////////////////////////////
  136. DEF_GM(return new ImageAlphaThresholdGM(true);)
  137. DEF_GM(return new ImageAlphaThresholdGM(false);)
  138. DEF_GM(return new ImageAlphaThresholdSurfaceGM();)
  139. //////////////////////////////////////////////////////////////////////////////
  140. static sk_sp<SkImage> make_img() {
  141. SkBitmap bitmap;
  142. bitmap.allocPixels(SkImageInfo::MakeS32(WIDTH, HEIGHT, kPremul_SkAlphaType));
  143. SkCanvas canvas(bitmap);
  144. SkPaint paint;
  145. SkRect rect = SkRect::MakeWH(WIDTH, HEIGHT);
  146. SkRandom rnd;
  147. while (!rect.isEmpty()) {
  148. paint.setColor(rnd.nextU() | (0xFF << 24));
  149. canvas.drawRect(rect, paint);
  150. rect.inset(25, 25);
  151. }
  152. return SkImage::MakeFromBitmap(bitmap);
  153. }
  154. DEF_SIMPLE_GM_BG(imagealphathreshold_image, canvas, WIDTH * 2, HEIGHT, SK_ColorBLACK) {
  155. sk_sp<SkImage> image(make_img());
  156. SkIRect rects[2];
  157. rects[0] = SkIRect::MakeXYWH(0, 150, WIDTH, HEIGHT - 300);
  158. rects[1] = SkIRect::MakeXYWH(150, 0, WIDTH - 300, HEIGHT);
  159. SkRegion region;
  160. region.setRects(rects, 2);
  161. SkPaint filterPaint;
  162. sk_sp<SkImageFilter> imageSource(SkImageSource::Make(image));
  163. filterPaint.setImageFilter(SkAlphaThresholdFilter::Make(region, 0.2f, 0.7f,
  164. std::move(imageSource)));
  165. canvas->saveLayer(nullptr, &filterPaint);
  166. canvas->restore();
  167. canvas->translate(WIDTH, 0);
  168. canvas->drawImage(image, 0, 0);
  169. }