Last active
January 23, 2021 00:12
-
-
Save flar/d30027c001a812ae7f3f4d2ca1aa8fd3 to your computer and use it in GitHub Desktop.
Workaround for Image widget not applying the filter quality unless you force it to change size via the "fit" operation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:typed_data'; | |
import 'dart:ui' as ui; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter/services.dart'; | |
void main() { | |
runApp(ImageTestApp()); | |
} | |
class ImageTestApp extends StatefulWidget { | |
@override | |
State createState() => ImageTestAppState(); | |
} | |
class ImageTestAppState extends State<ImageTestApp> { | |
final isCanvasKit = const bool.fromEnvironment('FLUTTER_WEB_USE_SKIA', defaultValue: false); | |
bool padTweak = false; | |
bool boxTweak = false; | |
Map<String, ui.Image> uiImages = {}; | |
@override | |
void initState() { | |
super.initState(); | |
_loadImages(); | |
} | |
Future<void> _loadImages() async { | |
await _loadImage('images/sample.png'); | |
await _loadImage('images/sample2.png'); | |
await _loadImage('images/sample3.png'); | |
setState(() async { | |
}); | |
} | |
Future<void> _loadImage(String imageFile) async { | |
ByteData bd = await rootBundle.load(imageFile); | |
final Uint8List bytes = Uint8List.view(bd.buffer); | |
final ui.Codec codec = await ui.instantiateImageCodec(bytes); | |
final ui.Image image = (await codec.getNextFrame()).image; | |
uiImages[imageFile] = image; | |
} | |
Widget tweakedImage(ImageProvider provider, FilterQuality quality, Size size) { | |
Image image = Image( | |
image: provider, | |
filterQuality: quality, | |
fit: BoxFit.fill, | |
width: padTweak ? size.width + 0.001 : null, | |
height: padTweak ? size.height + 0.001 : null, | |
); | |
if (!boxTweak) return image; | |
return SizedBox( | |
width: size.width + 0.001, | |
height: size.height + 0.001, | |
child: image, | |
); | |
} | |
Widget wrap(String imageFile, Size size) { | |
ImageProvider provider = AssetImage(imageFile); | |
return Row( | |
children: <Widget>[ | |
tweakedImage(provider, FilterQuality.none, size), | |
tweakedImage(provider, FilterQuality.low, size), | |
tweakedImage(provider, FilterQuality.high, size), | |
if (uiImages[imageFile] != null) | |
CustomPaint( | |
painter: _ImagePainter(uiImages[imageFile], FilterQuality.none), | |
child: SizedBox(width: size.width, height: size.height,), | |
), | |
if (uiImages[imageFile] != null) | |
CustomPaint( | |
painter: _ImagePainter(uiImages[imageFile], FilterQuality.low), | |
child: SizedBox(width: size.width, height: size.height,), | |
), | |
if (uiImages[imageFile] != null) | |
CustomPaint( | |
painter: _ImagePainter(uiImages[imageFile], FilterQuality.high), | |
child: SizedBox(width: size.width, height: size.height,), | |
), | |
], | |
); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
debugShowCheckedModeBanner: false, | |
home: Scaffold( | |
body: Container( | |
child: Container( | |
padding: const EdgeInsets.all(8.0), | |
width: double.infinity, | |
child: Column( | |
crossAxisAlignment: isCanvasKit ? CrossAxisAlignment.start : CrossAxisAlignment.end, | |
children: <Widget>[ | |
Text(isCanvasKit ? 'CanvasKit' : 'HTML'), | |
Row( | |
children: [ | |
Text('Pad Image size tweak: '), | |
Checkbox(value: padTweak, onChanged: (value) => setState(() { padTweak = value; }),), | |
SizedBox(width: 20), | |
Text('SizedBox tweak: '), | |
Checkbox(value: boxTweak, onChanged: (value) => setState(() { boxTweak = value; }),), | |
], | |
), | |
SizedBox(height: 20), | |
wrap('images/sample2.png', Size(200, 200)), | |
wrap('images/sample.png', Size(100, 100)), | |
wrap('images/sample3.png', Size(60, 60)), | |
], | |
), | |
), | |
), | |
), | |
); | |
} | |
} | |
class _ImagePainter extends CustomPainter { | |
_ImagePainter(this.image, this.filterQuality); | |
final ui.Image image; | |
final FilterQuality filterQuality; | |
@override | |
void paint(Canvas canvas, Size size) { | |
canvas.drawImage(image, Offset.zero, Paint()..filterQuality = filterQuality); | |
} | |
@override | |
bool shouldRepaint(CustomPainter oldDelegate) => true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment