2022-09-10 19:50:48 -07:00
import ' dart:typed_data ' ;
import ' dart:ui ' as ui ;
2023-02-09 23:00:34 +09:00
import ' package:flutter/widgets.dart ' ;
2022-09-10 19:50:48 -07:00
Future < ui . Image > decodeImageFromPixels (
Uint8List pixels ,
int width ,
int height ,
ui . PixelFormat format , {
int ? rowBytes ,
int ? targetWidth ,
int ? targetHeight ,
2023-02-15 16:44:40 +08:00
VoidCallback ? onPixelsCopied ,
2022-09-10 19:50:48 -07:00
bool allowUpscaling = true ,
} ) async {
if ( targetWidth ! = null ) {
assert ( allowUpscaling | | targetWidth < = width ) ;
}
if ( targetHeight ! = null ) {
assert ( allowUpscaling | | targetHeight < = height ) ;
}
final ui . ImmutableBuffer buffer =
await ui . ImmutableBuffer . fromUint8List ( pixels ) ;
2023-02-15 16:44:40 +08:00
onPixelsCopied ? . call ( ) ;
2022-09-10 19:50:48 -07:00
final ui . ImageDescriptor descriptor = ui . ImageDescriptor . raw (
buffer ,
width: width ,
height: height ,
rowBytes: rowBytes ,
pixelFormat: format ,
) ;
if ( ! allowUpscaling ) {
2022-09-11 19:52:38 -07:00
if ( targetWidth ! = null & & targetWidth > descriptor . width ) {
2022-09-10 19:50:48 -07:00
targetWidth = descriptor . width ;
}
2022-09-11 19:52:38 -07:00
if ( targetHeight ! = null & & targetHeight > descriptor . height ) {
2022-09-10 19:50:48 -07:00
targetHeight = descriptor . height ;
}
}
final ui . Codec codec = await descriptor . instantiateCodec (
targetWidth: targetWidth ,
targetHeight: targetHeight ,
) ;
final ui . FrameInfo frameInfo = await codec . getNextFrame ( ) ;
codec . dispose ( ) ;
buffer . dispose ( ) ;
descriptor . dispose ( ) ;
return frameInfo . image ;
}
2023-02-09 23:00:34 +09:00
class ImagePainter extends CustomPainter {
ImagePainter ( {
required this . image ,
required this . x ,
required this . y ,
required this . scale ,
} ) ;
ui . Image ? image ;
double x ;
double y ;
double scale ;
@ override
void paint ( Canvas canvas , Size size ) {
if ( image = = null ) return ;
if ( x . isNaN | | y . isNaN ) return ;
canvas . scale ( scale , scale ) ;
// https://github.com/flutter/flutter/issues/76187#issuecomment-784628161
// https://api.flutter-io.cn/flutter/dart-ui/FilterQuality.html
var paint = Paint ( ) ;
if ( ( scale - 1.0 ) . abs ( ) > 0.001 ) {
paint . filterQuality = FilterQuality . medium ;
if ( scale > 10.00000 ) {
paint . filterQuality = FilterQuality . high ;
}
}
canvas . drawImage (
image ! , Offset ( x . toInt ( ) . toDouble ( ) , y . toInt ( ) . toDouble ( ) ) , paint ) ;
}
@ override
bool shouldRepaint ( CustomPainter oldDelegate ) {
return oldDelegate ! = this ;
}
}