Reputation: 3590
In my Flutter project, I use a CustomPainter
to draw a custom shape.
In that CustomPainter
, I need to draw a png image, which is available in my assets folder in multiple sizes, so I can get the right image for the right screen density:
assets
\1.5x
image.png // 54 x 54 pixels
\2.0x
image.png // 72 x 72 pixels
\3.0x
image.png // 108 x 108 pixels
\4.0x
image.png // 144 x 144 pixels
image.png // 36 x 36 pixels
Here is how I load my image, to get an Image
file:
import 'dart:ui' as ui;
Future<ui.Image> getImage() async {
AssetImage assetImage = AssetImage("assets/image.png");
ImageStream stream = assetImage.resolve(createLocalImageConfiguration(context));
Completer<ui.Image> completer = Completer();
stream.addListener(ImageStreamListener((Imageinfo image, _) {
return completer.complete(image.image);
}
return completer.future;
}
And in my CustomPainter.paint()
function, here is how I draw the Image
, once loaded:
@override
void paint(Canvas canvas, Size size) {
// ...
canvas.drawImage(
myImage, // <- the loaded image
Offset(20, 20),
Paint()
);
}
I have two problems:
canvas.drawImageRect()
to draw an image of 36 x 36 points, the drawn image is sometimes still glitchy, depending on the image. And yes, I doubled checked the size of the original images.So what should I do to draw on my canvas
the right image for the right screen density, so it's drawn properly?
Thanks.
Upvotes: 6
Views: 9415
Reputation: 3590
Here is how I finally got it to work (thanks @pskink):
Step 1: return the whole ImageInfo
object, and not only the image:
Future<ImageInfo> getImageInfo(BuildContext context) async {
AssetImage assetImage = AssetImage("assets/image.png");
ImageStream stream = assetImage.resolve(createLocalImageConfiguration(context));
Completer<ImageInfo> completer = Completer();
stream.addListener(ImageStreamListener((Imageinfo imageInfo, _) {
return completer.complete(imageInfo);
}
return completer.future;
}
Step 2: use the ImageInfo.scale
property, and some filtering, to draw the image:
@override
void paint(Canvas canvas, Size size) {
// ...
paintImage(
canvas: canvas,
rect: Rect.fromLTWH(
20, 20,
myImageInfo.width / myImageInfo.scale,
myImageInfo.height / myImageInfo.scale),
image: myImageInfo.image, // <- the loaded image
filterQuality: FilterQuality.low,
);
}
Upvotes: 5