• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:async';
6import 'dart:io';
7import 'dart:typed_data';
8import 'dart:ui';
9
10import 'package:path/path.dart' as path;
11import 'package:test/test.dart';
12
13const int _kWidth = 10;
14const int _kRadius = 2;
15
16const Color _kBlack = const Color.fromRGBO(0, 0, 0, 1.0);
17const Color _kGreen = const Color.fromRGBO(0, 255, 0, 1.0);
18
19void main() {
20  group('Image.toByteData', () {
21    group('RGBA format', () {
22      test('works with simple image', () async {
23        final Image image = await Square4x4Image.image;
24        final ByteData data = await image.toByteData();
25        expect(Uint8List.view(data.buffer), Square4x4Image.bytes);
26      });
27
28      test('converts grayscale images', () async {
29        final Image image = await GrayscaleImage.load();
30        final ByteData data = await image.toByteData();
31        final Uint8List bytes = data.buffer.asUint8List();
32        expect(bytes, hasLength(16));
33        expect(bytes, GrayscaleImage.bytesAsRgba);
34      });
35    });
36
37    group('Unmodified format', () {
38      test('works with simple image', () async {
39        final Image image = await Square4x4Image.image;
40        final ByteData data = await image.toByteData(format: ImageByteFormat.rawUnmodified);
41        expect(Uint8List.view(data.buffer), Square4x4Image.bytes);
42      });
43
44      test('works with grayscale images', () async {
45        final Image image = await GrayscaleImage.load();
46        final ByteData data = await image.toByteData(format: ImageByteFormat.rawUnmodified);
47        final Uint8List bytes = data.buffer.asUint8List();
48        expect(bytes, hasLength(4));
49        expect(bytes, GrayscaleImage.bytesUnmodified);
50      });
51    });
52
53    group('PNG format', () {
54      test('works with simple image', () async {
55        final Image image = await Square4x4Image.image;
56        final ByteData data = await image.toByteData(format: ImageByteFormat.png);
57        final List<int> expected = await readFile('square.png');
58        expect(Uint8List.view(data.buffer), expected);
59      });
60    });
61  });
62}
63
64class Square4x4Image {
65  Square4x4Image._();
66
67  static Future<Image> get image async {
68    final double width = _kWidth.toDouble();
69    final double radius = _kRadius.toDouble();
70    final double innerWidth = (_kWidth - 2 * _kRadius).toDouble();
71
72    final PictureRecorder recorder = PictureRecorder();
73    final Canvas canvas =
74        Canvas(recorder, Rect.fromLTWH(0.0, 0.0, width, width));
75
76    final Paint black = Paint()
77      ..strokeWidth = 1.0
78      ..color = _kBlack;
79    final Paint green = Paint()
80      ..strokeWidth = 1.0
81      ..color = _kGreen;
82
83    canvas.drawRect(Rect.fromLTWH(0.0, 0.0, width, width), black);
84    canvas.drawRect(
85        Rect.fromLTWH(radius, radius, innerWidth, innerWidth), green);
86    return await recorder.endRecording().toImage(_kWidth, _kWidth);
87  }
88
89  static List<int> get bytes {
90    const int bytesPerChannel = 4;
91    final List<int> result = List<int>(_kWidth * _kWidth * bytesPerChannel);
92
93    void fillWithColor(Color color, int min, int max) {
94      for (int i = min; i < max; i++) {
95        for (int j = min; j < max; j++) {
96          final int offset = i * bytesPerChannel + j * _kWidth * bytesPerChannel;
97          result[offset] = color.red;
98          result[offset + 1] = color.green;
99          result[offset + 2] = color.blue;
100          result[offset + 3] = color.alpha;
101        }
102      }
103    }
104
105    fillWithColor(_kBlack, 0, _kWidth);
106    fillWithColor(_kGreen, _kRadius, _kWidth - _kRadius);
107
108    return result;
109  }
110}
111
112class GrayscaleImage {
113  GrayscaleImage._();
114
115  static Future<Image> load() async {
116    final Uint8List bytes = await readFile('4x4.png');
117    final Completer<Image> completer = Completer<Image>();
118    decodeImageFromList(bytes, (Image image) => completer.complete(image));
119    return await completer.future;
120  }
121
122  static List<int> get bytesAsRgba {
123    return <int>[
124      255, 255, 255, 255,
125      127, 127, 127, 255,
126      127, 127, 127, 255,
127      0, 0, 0, 255,
128    ];
129  }
130
131  static List<int> get bytesUnmodified => <int>[255, 127, 127, 0];
132}
133
134Future<Uint8List> readFile(String fileName) async {
135  final File file = File(path.join('flutter', 'testing', 'resources', fileName));
136  return await file.readAsBytes();
137}
138