Skip to content

Instantly share code, notes, and snippets.

@netsmertia
Created May 4, 2018 13:53
Show Gist options
  • Star 55 You must be signed in to star a gist
  • Fork 15 You must be signed in to fork a gist
  • Save netsmertia/9c588f23391c781fa1eb791f0dce0768 to your computer and use it in GitHub Desktop.
Save netsmertia/9c588f23391c781fa1eb791f0dce0768 to your computer and use it in GitHub Desktop.
flutter image drawing in canvas
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import 'package:flutter/services.dart' show rootBundle;
import 'dart:async';
import 'dart:typed_data';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ui.Image image;
bool isImageloaded = false;
void initState() {
super.initState();
init();
}
Future <Null> init() async {
final ByteData data = await rootBundle.load('images/lake.jpg');
image = await loadImage(new Uint8List.view(data.buffer));
}
Future<ui.Image> loadImage(List<int> img) async {
final Completer<ui.Image> completer = new Completer();
ui.decodeImageFromList(img, (ui.Image img) {
setState(() {
isImageloaded = true;
});
return completer.complete(img);
});
return completer.future;
}
Widget _buildImage() {
if (this.isImageloaded) {
return new CustomPaint(
painter: new ImageEditor(image: image),
);
} else {
return new Center(child: new Text('loading'));
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Container(
child: _buildImage(),
)
);
}
}
class ImageEditor extends CustomPainter {
ImageEditor({
this.image,
});
ui.Image image;
@override
void paint(Canvas canvas, Size size) {
ByteData data = image.toByteData();
canvas.drawImage(image, new Offset(0.0, 0.0), new Paint());
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
@dingjianjaja
Copy link

love you

@bus710
Copy link

bus710 commented Jul 9, 2019

love you (2)

@thaouit
Copy link

thaouit commented Aug 1, 2019

love you (3)

@SangYeonLeeSam
Copy link

wow great thx~!

@tkwant
Copy link

tkwant commented Sep 11, 2019

thx.

Copy link

ghost commented Sep 24, 2019

hey @netsmertia how to rotate that image we are using for canvas.drawImage.
I use my custom image but now I want to rotate that but when I use canvas.rotate then black output is occurring

@thaouit
Copy link

thaouit commented Sep 24, 2019

https://pub.dev/packages/flutter_image_compress#rotate
FlutterImageCompress.compressAndGetFile(filePath, rotatePath, minHeight: 480, minWidth: 400, rotate: -90);

@wangyongf
Copy link

love you 3000 times!

@Bruising6802
Copy link

thx

@Bruising6802
Copy link

Bruising6802 commented Nov 8, 2019

Where do you put FlutterImageCompress.compressAndGetFile(filePath, rotatePath, minHeight: 480, minWidth: 400, rotate: -90); in which line? what do you mean with target path

@Maxvyr
Copy link

Maxvyr commented Mar 11, 2020

thank you very much =)

@KevinRohn
Copy link

thank you!!

@softmarshmallow
Copy link

How to load & draw image independently just on custom painter?

@mozhaiskyi
Copy link

love you

@BoHellgren
Copy link

If the image is not an asset image, but a file stored on the device, and its path is known, you can do like this:

            Future<ui.Image> loadImage(Uint8List bytes) async {
              final Completer<ui.Image> completer = Completer();
              ui.decodeImageFromList(bytes, (ui.Image img) {
                return completer.complete(img);
              });
              return completer.future;
            }

           File file = File(thePath);
           Uint8List bytes = await file.readAsBytes();
           ui.Image backgroundImage = await loadImage(bytes);

and in the Custom Painter:

    canvas.drawImage(backgroundImage, Offset(0.0, 0.0), Paint());

Works with both .png and .jpg files.

@desmeit
Copy link

desmeit commented Apr 19, 2021

how could I change the size of the image?

@nhtonmoy
Copy link

nhtonmoy commented Aug 4, 2021

If the image is not an asset image, but a file stored on the device, and its path is known, you can do like this:

            Future<ui.Image> loadImage(Uint8List bytes) async {
              final Completer<ui.Image> completer = Completer();
              ui.decodeImageFromList(bytes, (ui.Image img) {
                return completer.complete(img);
              });
              return completer.future;
            }

           File file = File(thePath);
           Uint8List bytes = await file.readAsBytes();
           ui.Image backgroundImage = await loadImage(bytes);

and in the Custom Painter:

    canvas.drawImage(backgroundImage, Offset(0.0, 0.0), Paint());

Works with both .png and .jpg files.

Thanks a lot!!

@raumeunier
Copy link

hello

after testing your code it seems that something has changed the image loading does not work anymore

these normal?

cdl remy

@ilyasaktass
Copy link

How can I add the eraser mode on canvas but the eraser should not erase the picture?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment