Skip to content

Instantly share code, notes, and snippets.

@netsmertia
Created May 4, 2018 13:53
Show Gist options
  • Select an option

  • Save netsmertia/9c588f23391c781fa1eb791f0dce0768 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

love you

@bus710

bus710 commented Jul 9, 2019

Copy link
Copy Markdown

love you (2)

@thaouit

thaouit commented Aug 1, 2019

Copy link
Copy Markdown

love you (3)

@SangYeonLeeSam

Copy link
Copy Markdown

wow great thx~!

@tkwant

tkwant commented Sep 11, 2019

Copy link
Copy Markdown

thx.

ghost commented Sep 24, 2019

Copy link
Copy Markdown

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

thaouit commented Sep 24, 2019

Copy link
Copy Markdown

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

@wangyongf

Copy link
Copy Markdown

love you 3000 times!

@Bruising6802

Copy link
Copy Markdown

thx

@Bruising6802

Bruising6802 commented Nov 8, 2019

Copy link
Copy Markdown

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

Maxvyr commented Mar 11, 2020

Copy link
Copy Markdown

thank you very much =)

@KevinRohn

Copy link
Copy Markdown

thank you!!

@softmarshmallow

Copy link
Copy Markdown

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

@mozhaiskyi

Copy link
Copy Markdown

love you

@BoHellgren

Copy link
Copy Markdown

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

desmeit commented Apr 19, 2021

Copy link
Copy Markdown

how could I change the size of the image?

@nhtonmoy

nhtonmoy commented Aug 4, 2021

Copy link
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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

@Zobam

Zobam commented Feb 15, 2025

Copy link
Copy Markdown

This was very helpful. Thank you

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