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