Skip to content

Commit

Permalink
Added negative test and blur test to the wide gamut tests. (#120914)
Browse files Browse the repository at this point in the history
* Added negative test and blur test to the wide gamut tests.

* switched back to dstOver

* fixed blur test

* analysis warnings

* analyzer
  • Loading branch information
gaaclarke authored Feb 22, 2023
1 parent dad9eb2 commit 4c25587
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ bool _isAlmost(double x, double y, double epsilon) {
return (x - y).abs() < epsilon;
}

bool _findDeepRedBGRA10(Uint8List bytes, int width, int height) {
List<double> _deepRed = <double>[1.0931, -0.2268, -0.1501];

bool _findBGRA10Color(
Uint8List bytes, int width, int height, List<double> color) {
final ByteData byteData = ByteData.sublistView(bytes);
expect(bytes.lengthInBytes, width * height * 8);
expect(bytes.lengthInBytes, byteData.lengthInBytes);
Expand All @@ -33,16 +36,17 @@ bool _findDeepRedBGRA10(Uint8List bytes, int width, int height) {
final double blue = _decodeBGR10((pixel >> 6) & 0x3ff);
final double green = _decodeBGR10((pixel >> 22) & 0x3ff);
final double red = _decodeBGR10((pixel >> 38) & 0x3ff);
if (_isAlmost(red, 1.0931, 0.01) &&
_isAlmost(green, -0.2268, 0.01) &&
_isAlmost(blue, -0.1501, 0.01)) {
if (_isAlmost(red, color[0], 0.01) &&
_isAlmost(green, color[1], 0.01) &&
_isAlmost(blue, color[2], 0.01)) {
foundDeepRed = true;
}
}
return foundDeepRed;
}

bool _findDeepRedBGR10(Uint8List bytes, int width, int height) {
bool _findBGR10Color(
Uint8List bytes, int width, int height, List<double> color) {
final ByteData byteData = ByteData.sublistView(bytes);
expect(bytes.lengthInBytes, width * height * 4);
expect(bytes.lengthInBytes, byteData.lengthInBytes);
Expand All @@ -52,25 +56,25 @@ bool _findDeepRedBGR10(Uint8List bytes, int width, int height) {
final double blue = _decodeBGR10(pixel & 0x3ff);
final double green = _decodeBGR10((pixel >> 10) & 0x3ff);
final double red = _decodeBGR10((pixel >> 20) & 0x3ff);
if (_isAlmost(red, 1.0931, 0.01) &&
_isAlmost(green, -0.2268, 0.01) &&
_isAlmost(blue, -0.1501, 0.01)) {
if (_isAlmost(red, color[0], 0.01) &&
_isAlmost(green, color[1], 0.01) &&
_isAlmost(blue, color[2], 0.01)) {
foundDeepRed = true;
}
}
return foundDeepRed;
}

bool _findDeepRed(List<Object?> result) {
bool _findColor(List<Object?> result, List<double> color) {
expect(result, isNotNull);
expect(result.length, 4);
final int width = (result[0] as int?)!;
final int height = (result[1] as int?)!;
final String format = (result[2] as String?)!;
if (format == 'MTLPixelFormatBGR10_XR') {
return _findDeepRedBGR10((result[3] as Uint8List?)!, width, height);
return _findBGR10Color((result[3] as Uint8List?)!, width, height, color);
} else if (format == 'MTLPixelFormatBGRA10_XR') {
return _findDeepRedBGRA10((result[3] as Uint8List?)!, width, height);
return _findBGRA10Color((result[3] as Uint8List?)!, width, height, color);
} else {
fail('Unsupported pixel format: $format');
}
Expand All @@ -87,7 +91,7 @@ void main() {
const MethodChannel channel = MethodChannel('flutter/screenshot');
final List<Object?> result =
await channel.invokeMethod('test') as List<Object?>;
expect(_findDeepRed(result), isTrue);
expect(_findColor(result, _deepRed), isTrue);
});
testWidgets('look for display p3 deepest red', (WidgetTester tester) async {
app.run(app.Setup.canvasSaveLayer);
Expand All @@ -96,7 +100,27 @@ void main() {
const MethodChannel channel = MethodChannel('flutter/screenshot');
final List<Object?> result =
await channel.invokeMethod('test') as List<Object?>;
expect(_findDeepRed(result), isTrue);
expect(_findColor(result, _deepRed), isTrue);
});
testWidgets('no p3 deepest red without image', (WidgetTester tester) async {
app.run(app.Setup.none);
await tester.pumpAndSettle(const Duration(seconds: 2));

const MethodChannel channel = MethodChannel('flutter/screenshot');
final List<Object?> result =
await channel.invokeMethod('test') as List<Object?>;
expect(_findColor(result, _deepRed), isFalse);
expect(_findColor(result, <double>[0.0, 1.0, 0.0]), isFalse);
});
testWidgets('p3 deepest red with blur', (WidgetTester tester) async {
app.run(app.Setup.blur);
await tester.pumpAndSettle(const Duration(seconds: 2));

const MethodChannel channel = MethodChannel('flutter/screenshot');
final List<Object?> result =
await channel.invokeMethod('test') as List<Object?>;
expect(_findColor(result, _deepRed), isTrue);
expect(_findColor(result, <double>[0.0, 1.0, 0.0]), isTrue);
});
});
}
214 changes: 151 additions & 63 deletions dev/integration_tests/wide_gamut_test/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,67 +8,140 @@ import 'package:flutter/material.dart';

/// A 100x100 png in Display P3 colorspace.
const String _displayP3Logo =
'iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAABdWlDQ1BrQ0dDb2xvclNwYWNlRG'
'lzcGxheVAzAAAokXWQvUvDUBTFT6tS0DqIDh0cMolD1NIKdnFoKxRFMFQFq1OafgltfCQpUnET'
'Vyn4H1jBWXCwiFRwcXAQRAcR3Zw6KbhoeN6XVNoi3sfl/Ticc7lcwBtQGSv2AijplpFMxKS11L'
'rke4OHnlOqZrKooiwK/v276/PR9d5PiFlNu3YQ2U9cl84ul3aeAlN//V3Vn8maGv3f1EGNGRbg'
'kYmVbYsJ3iUeMWgp4qrgvMvHgtMunzuelWSc+JZY0gpqhrhJLKc79HwHl4plrbWD2N6f1VeXxR'
'zqUcxhEyYYilBRgQQF4X/8044/ji1yV2BQLo8CLMpESRETssTz0KFhEjJxCEHqkLhz634PrfvJ'
'bW3vFZhtcM4v2tpCAzidoZPV29p4BBgaAG7qTDVUR+qh9uZywPsJMJgChu8os2HmwiF3e38M6H'
'vh/GMM8B0CdpXzryPO7RqFn4Er/QcXKWq8UwZBywAAAJplWElmTU0AKgAAAAgABQESAAMAAAAB'
'AAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgExAAIAAAAhAAAAWodpAAQAAAABAAAAfAAAAA'
'AAAABIAAAAAQAAAEgAAAABQWRvYmUgUGhvdG9zaG9wIDI0LjEgKE1hY2ludG9zaCkAAAACoAIA'
'BAAAAAEAAABkoAMABAAAAAEAAABkAAAAALGpdjYAAAAJcEhZcwAACxMAAAsTAQCanBgAAAR2aV'
'RYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1l'
'dGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaH'
'R0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6'
'RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly'
'9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDov'
'L25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dH'
'A6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAg'
'IHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aW'
'ZmOllSZXNvbHV0aW9uPjcyPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVz'
'b2x1dGlvbj43MjwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb2'
'4+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHhtcE1NOkRlcml2ZWRGcm9tIHJkZjpw'
'YXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgPHN0UmVmOmluc3RhbmNlSUQ+eG1wLm'
'lpZDpDREE0Mzc3NzhBRjcxMUVEQTU0N0JCNjBEMjUwOTI2RDwvc3RSZWY6aW5zdGFuY2VJRD4K'
'ICAgICAgICAgICAgPHN0UmVmOmRvY3VtZW50SUQ+eG1wLmRpZDpDREE0Mzc3ODhBRjcxMUVEQT'
'U0N0JCNjBEMjUwOTI2RDwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJp'
'dmVkRnJvbT4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+eG1wLmRpZDpDREE0Mzc3QThBRj'
'cxMUVEQTU0N0JCNjBEMjUwOTI2RDwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1N'
'Okluc3RhbmNlSUQ+eG1wLmlpZDpDREE0Mzc3OThBRjcxMUVEQTU0N0JCNjBEMjUwOTI2RDwveG'
'1wTU06SW5zdGFuY2VJRD4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3No'
'b3AgMjQuMSAoTWFjaW50b3NoKTwveG1wOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcm'
'lwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KRm6gbQAABNpJREFUeAHtnOty3CAM'
'hZO2Pzrt+z9qO/3RS/iSOVPGwcTrFZLwoqlDfUPifAgc75Lnf09P5d+yLAp8yhLIiuNNgQUkWU'
'9YQBaQZAokC2dlyAKSTIFk4awMWUCSKZAsnJUhyYB8SRbPkHB4FfG3bM8DaqduerVV3ZcFglCI'
'9KdsP8tm/X6IuoH8uWzfyraAFBH2rIbxo1yk/b3rzxwXjO/lZisYxHG5OUTikxmjYOCDzLCGUa'
'q8FpDZYVwKSAQMfFrbJYasKBiWc4fATg8kAgbijYBBvVMDiYKBcKNsWiARMPA52qYEEgVj1DBV'
'Q54OSAQMBPOAgZ+pgETA8BimACGbBkgUDK/MmArIo8AAynNprHdWqjPcVM76buqmRpaLUw9Z6i'
'meMOTzViGtrk8LBGEYv71heM8ZW5ApgUTAQJhoGMSQDkgUDMTIYKmARMDAZyZLAyQKRoZhqu4Q'
'KYBEwECEbDCIKRxIFAwan9FCgUTAwGdmCwMSBSPjMFV3kBAgETBodHYYxOgOJAJG9mEKEDJXIF'
'EwZsgMdyALhiTvly4ZsmD0IdRnhwOJgEEDZxqm3IBEwMDnzDYsQ6JgzJoZ6kRDgCwYkvf20hxI'
'BAyaPXtmCJ3pkrYIGPKpBrVKrhm5xpDOYNWzTYEQWJbPwAWKeDzWGBY3JmYF9jUYTxg43Bumtj'
'DIDmujTsRjwaeliGYZ4g2jJ7B3pvZiufWcGVzLcbRuBL396AJLrsUydY63iI7/NANCRaxKRTwJ'
'czyM9pVbGL16OeedGb142i36+KgZEFwhCGOqBZQWDOpvWQ1DE/jeta37jxzbxsM91j6o0xQIQV'
'tkyi2Nr2GwLn3E463isfyLDYjfMlMg9BgJdHb4UuO1KJ/9PZMvrznDVKydRpn7uAdKC8besOAN'
'Q+3a0dHssDkQIlPwlEczZQtD9VBuLQrGXufYxnfP/hAgBHQLlBaMvUZFwFB79mKyPD4MiBohAf'
'cy5SwMr6cp4vO0oUBoSC9TtjB6jeccdWkCH/k0VT9QeAxT6CRzW9ImQSl5PP1dNt7bqPHlv7um'
'ewVD+7s3nDhBnUffCJyo/vAtbkCISELSu3+V7WvZPkpR3fMIMIocuRd9RsCQT8SJsI86aERMrz'
'4lDJnhOYF7zxlbgc1ev28rvme/huH5Z/qiYaBZugyJgnFPB7K8Nx0QeimT/sjMoNF6uqMDZLJ0'
'Q5bn05SyMROQlBkyciwHAhmY1Vx/DzkqAqIxZJEt1nCUFfWrHGsfR9vZui5dhrQEawV+9hjib4'
'Gzn8XSAZFglHUvthRMPuoszAIlHRCERzDsEaGkBPKG4/+7L89Mke+oMjWQiEwBROTwlRqIeikC'
'PcrwNQWQiEzBZ0SmTAEkMlPk26ucCkhEpgDCM1OmAqJeeuU5ZUogGt8pPR+JPTJlSiBkShQUZe'
'moclogUVDwOzJTpgYSBUXZiX9rmx4IgkigK8wplwAiKCpnnugvAwQYmNcjMV9NGvEBWspPDF+V'
'veOHoFDqM487qnt3a2uIfHfRyQOXBFJrARR6s+WXs2vgwLFcq355IIKDiCMNMBaW7mtAFo1q1W'
'ElWKtuy2OXm9QtxYmoawGJUL3jcwHpiBNxagGJUL3jcwHpiBNxagGJUL3jcwHpiBNxagGJUL3j'
'cwHpiBNx6gU/2fLWVmm7wQAAAABJRU5ErkJggg==';

void main() => run(Setup.canvasSaveLayer);
'iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAABdWlDQ1BrQ0dDb2xv'
'clNwYWNlRGlzcGxheVAzAAAokXWQvUvDUBTFT6tS0DqIDh0cMolD1NIKdnFoKxRF'
'MFQFq1OafgltfCQpUnETVyn4H1jBWXCwiFRwcXAQRAcR3Zw6KbhoeN6XVNoi3sfl'
'/Ticc7lcwBtQGSv2AijplpFMxKS11Lrke4OHnlOqZrKooiwK/v276/PR9d5PiFlN'
'u3YQ2U9cl84ul3aeAlN//V3Vn8maGv3f1EGNGRbgkYmVbYsJ3iUeMWgp4qrgvMvH'
'gtMunzuelWSc+JZY0gpqhrhJLKc79HwHl4plrbWD2N6f1VeXxRzqUcxhEyYYilBR'
'gQQF4X/8044/ji1yV2BQLo8CLMpESRETssTz0KFhEjJxCEHqkLhz634PrfvJbW3v'
'FZhtcM4v2tpCAzidoZPV29p4BBgaAG7qTDVUR+qh9uZywPsJMJgChu8os2HmwiF3'
'e38M6Hvh/GMM8B0CdpXzryPO7RqFn4Er/QcXKWq8UwZBywAAANplWElmTU0AKgAA'
'AAgABgESAAMAAAABAAEAAAEaAAUAAAABAAAAVgEbAAUAAAABAAAAXgExAAIAAAAh'
'AAAAZgEyAAIAAAAUAAAAiIdpAAQAAAABAAAAnAAAAAAAAABIAAAAAQAAAEgAAAAB'
'QWRvYmUgUGhvdG9zaG9wIDI0LjEgKE1hY2ludG9zaCkAADIwMjM6MDI6MDggMTA6'
'MTY6NDQAAAOQBAACAAAAFAAAAMagAgAEAAAAAQAAAGSgAwAEAAAAAQAAAGQAAAAA'
'MjAyMzowMjowOCAxMDoxMzoyMgBgamvuAAAACXBIWXMAAAsTAAALEwEAmpwYAAAL'
'v2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJh'
'ZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRm'
'OlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRm'
'LXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0i'
'IgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3Rp'
'ZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9k'
'Yy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9u'
'cy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJo'
'dHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxu'
'czpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291'
'cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFk'
'b2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAg'
'eG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8x'
'LjAvIj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+NzI8L3RpZmY6WVJlc29s'
'dXRpb24+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50'
'YXRpb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyPC90aWZmOlhSZXNv'
'bHV0aW9uPgogICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3BuZzwvZGM6Zm9ybWF0'
'PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAyMy0wMi0wOFQxMDoxNjo0NC0w'
'ODowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+'
'QWRvYmUgUGhvdG9zaG9wIDI0LjEgKE1hY2ludG9zaCk8L3htcDpDcmVhdG9yVG9v'
'bD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMjMtMDItMDhUMTA6MTM6MjIt'
'MDg6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1ldGFkYXRhRGF0'
'ZT4yMDIzLTAyLTA4VDEwOjE2OjQ0LTA4OjAwPC94bXA6TWV0YWRhdGFEYXRlPgog'
'ICAgICAgICA8eG1wTU06SGlzdG9yeT4KICAgICAgICAgICAgPHJkZjpTZXE+CiAg'
'ICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgog'
'ICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90'
'b3Nob3AgMjQuMSAoTWFjaW50b3NoKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAg'
'ICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4K'
'ICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAyMy0wMi0wOFQxMDoxNjo0'
'NC0wODowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omlu'
'c3RhbmNlSUQ+eG1wLmlpZDo3ZmM3YjMyNC0xNDUyLTQ2ZGUtODI2MC0yNGRmMTlh'
'YjdkNTc8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2'
'dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgPC9y'
'ZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVz'
'b3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5B'
'ZG9iZSBQaG90b3Nob3AgMjQuMSAoTWFjaW50b3NoKTwvc3RFdnQ6c29mdHdhcmVB'
'Z2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6'
'Y2hhbmdlZD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAyMy0wMi0w'
'OFQxMDoxNjo0NC0wODowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAg'
'PHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDpmM2UxNjllMy1jZmZhLTRjZjUtYmQ1'
'OS02YzgzODljYjk1MDk8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAg'
'ICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAg'
'ICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAg'
'PC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVu'
'dElEPnhtcC5kaWQ6Q0RBNDM3N0E4QUY3MTFFREE1NDdCQjYwRDI1MDkyNkQ8L3ht'
'cE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50'
'SUQ+YWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjA2M2QwNTUwLTVlNjctMjA0Mi1iN2Vl'
'LTg4ZDE2ZDc5MDAyYTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1N'
'OkRlcml2ZWRGcm9tIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAg'
'ICAgPHN0UmVmOmluc3RhbmNlSUQ+eG1wLmlpZDpDREE0Mzc3NzhBRjcxMUVEQTU0'
'N0JCNjBEMjUwOTI2RDwvc3RSZWY6aW5zdGFuY2VJRD4KICAgICAgICAgICAgPHN0'
'UmVmOmRvY3VtZW50SUQ+eG1wLmRpZDpDREE0Mzc3ODhBRjcxMUVEQTU0N0JCNjBE'
'MjUwOTI2RDwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJp'
'dmVkRnJvbT4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+eG1wLmlpZDpmM2Ux'
'NjllMy1jZmZhLTRjZjUtYmQ1OS02YzgzODljYjk1MDk8L3htcE1NOkluc3RhbmNl'
'SUQ+CiAgICAgICAgIDxwaG90b3Nob3A6SUNDUHJvZmlsZT5EaXNwbGF5IFAzPC9w'
'aG90b3Nob3A6SUNDUHJvZmlsZT4KICAgICAgICAgPHBob3Rvc2hvcDpDb2xvck1v'
'ZGU+MzwvcGhvdG9zaG9wOkNvbG9yTW9kZT4KICAgICAgICAgPHBob3Rvc2hvcDpE'
'b2N1bWVudEFuY2VzdG9ycz4KICAgICAgICAgICAgPHJkZjpCYWc+CiAgICAgICAg'
'ICAgICAgIDxyZGY6bGk+eG1wLmRpZDpDREE0Mzc3QThBRjcxMUVEQTU0N0JCNjBE'
'MjUwOTI2RDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpCYWc+CiAgICAgICAg'
'IDwvcGhvdG9zaG9wOkRvY3VtZW50QW5jZXN0b3JzPgogICAgICA8L3JkZjpEZXNj'
'cmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4Ka44gfwAACRBJREFU'
'eAHtnMtyHDUUhtvjccItUClSBQtY5wHCBpOq7L1K+UWy4QH8CjwHWeQVsiBskmUW'
'WcMCqgzhGiBz4/9knUHTTHvssW496VNR1K1WS0fn05Fa6h7vLZpG/wapxQKjWhQZ'
'9DizwACksp4wABmAVGaBytQZPGQAUpkFKlNn8JABSGUWqEydwUMqAzKuTJ8k6rAV'
'MVfYS1A6ZdOrY5W9s0AwFEaaKbxSiL0/RNlA3ld4R2EAIiN0SQjjT2Wy867826Qb'
'jHd1cywY6LFzc4gZH89IBYM68IzYMFTkbgHpO4ydAlICBnXGlp0YskrBiDl3GNje'
'AykBA+OlgEG5vQZSCgaGSyW9BVICBnWmll4CKQUj1TAVQu4dkBIwMFgOGNTTKyAl'
'YOQYpgBh0hsgpWDk8oxeAXlTYABlT43N7ZXWGS4V93Vv6lKNVOaqhyzrKTlhWJ2X'
'NWSs/NUCwTCM37lh5J4z2iCrfEF1HgwMputkgdVc5wtOEH+NiI62rwOG5LVCensL'
'nRtLS3VAMBSGCT0D63rDTv2lg+tNM77m8ypaCvleK/xz9kKPQ+y+0s42DKtT+YpL'
'VZO6GSaEITgkkzR6TwE4E4W/mualLnyv6z8o/l1JgLyh448Vf/J209w8UBpv9v44'
'i9xLPl3fCz1D564DKKpCqgFihjEYss5Chp0q/eB9ndDV/26aZ4oeKf2xwgsBOlWM'
'oZei/CMBuKX4tsI9Xbj/VtPcwZt+VRCMid70jXWfG84U1yVSmjG4aJBFXf0ajxa/'
'Kfwij5DxXpMu43L+tdLvdllO+mPcTttyL2XIq6ydr5V/Vrrd6+p3E+S6C7nS2jAE'
'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';

void main() => run(Setup.blur);

enum Setup {
none,
image,
canvasSaveLayer,
blur,
}

void run(Setup setup) {
Expand Down Expand Up @@ -104,18 +177,14 @@ class _SaveLayerDrawer extends CustomPainter {
center: Offset.zero,
width: _image!.width.toDouble(),
height: _image!.height.toDouble());
canvas.saveLayer(
imageRect,
Paint());
canvas.saveLayer(imageRect, Paint());
canvas.drawRect(
imageRect.inflate(-_image!.width.toDouble() / 4.0),
Paint()
..style = PaintingStyle.stroke
..color = const Color(0xffffffff)
..strokeWidth = 3);
canvas.saveLayer(
imageRect,
Paint()..blendMode = BlendMode.multiply);
canvas.saveLayer(imageRect, Paint()..blendMode = BlendMode.dstOver);
canvas.drawImage(_image!,
Offset(-_image!.width / 2.0, -_image!.height / 2.0), Paint());
canvas.restore();
Expand Down Expand Up @@ -165,12 +234,31 @@ class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
late Widget imageWidget;
switch (widget.setup) {
case Setup.none:
imageWidget = Container();
break;
case Setup.image:
imageWidget = Image.memory(base64Decode(_displayP3Logo));
break;
case Setup.canvasSaveLayer:
imageWidget = CustomPaint(painter: _SaveLayerDrawer(_image));
break;
case Setup.blur:
imageWidget = Stack(
children: <Widget>[
const ColoredBox(
color: Color(0xff00ff00),
child: SizedBox(
width: 100,
height: 100,
),
),
ImageFiltered(
imageFilter: ui.ImageFilter.blur(sigmaX: 6, sigmaY: 6),
child: Image.memory(base64Decode(_displayP3Logo))),
],
);
break;
}

return Scaffold(
Expand Down

0 comments on commit 4c25587

Please sign in to comment.