Unable to draw image on Flutter canvas

1,077

I am posting below a working code from my app which loads an image and show it in the flutter Canvas. Hope it helps the future readers.

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:ui' as ui;

class ImageInsideCanvasPage extends StatefulWidget {
  @override
  _ImageInsideCanvasPageState createState() => _ImageInsideCanvasPageState();
}

class _ImageInsideCanvasPageState extends State<ImageInsideCanvasPage> {
  ui.Image? image;

  @override
  void initState() {
    // Add your own asset image link
    _load('assets/img.png');
    super.initState();
  }

  void _load(String path) async {
    var bytes = await rootBundle.load(path);
    image = await decodeImageFromList(bytes.buffer.asUint8List());
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          child: CustomPaint(
            painter: ImageInsideCanvas(image: image),
            child: SizedBox.expand(),
          ),
        ),
      ),
    );
  }
}

class ImageInsideCanvas extends CustomPainter {
  ImageInsideCanvas({required this.image});
  ui.Image? image;

  @override
  void paint(Canvas canvas, Size size) async {
    Paint greenBrush = Paint()..color = Colors.greenAccent;
    canvas.save();
    canvas.drawImage(image!, Offset(0, 0), greenBrush);
    canvas.restore();
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

Share:
1,077
magee05
Author by

magee05

Software dev

Updated on November 21, 2022

Comments

  • magee05
    magee05 over 1 year

    I am currently trying to draw an image on a flutter canvas and then draw rectangles over the image to cover specific data. I am running into an issue where the the rectangles are drawing fine but the image is not being drawn behind. It appears as if it is not being drawn at all.

    I am loading the image into a Dart UI Image object from bytes. Once the image is loaded I create a PictureRecorder and pass it into a Canvas object. I then attempt to draw the image object first, followed by the rectangles over top. The complete code is below:

    import 'dart:async';
    import 'dart:typed_data';
    
    import 'dart:ui' as ui;
    
    import 'package:common/ocr/scraped_card_field.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    class ObfuscatedCardRenderer {
      ui.Image _backgroundImage;
    
      ///
      ///
      ///
      Future<ByteData> renderImage(
          Uint8List imageBytes, List<ScrapedCardField> fields) async {
        await _loadImageBackground(imageBytes);
        var obfuscatedImage = await _obfuscateImage(fields);
    
        var byteD =
            await obfuscatedImage.toByteData(format: ui.ImageByteFormat.png);
    
        return byteD;
      }
    
      ///
      ///
      ///
      Future<ui.Image> _obfuscateImage(List<ScrapedCardField> fields) async {
        ui.PictureRecorder recorder = ui.PictureRecorder();
        ui.Canvas c = ui.Canvas(recorder);
    
        var paint = ui.Paint();
    
        c.drawImage(_backgroundImage, ui.Offset(0.0, 0.0), new Paint());
        for (ScrapedCardField field in fields) {
          paint.color = Colors.white;
          c.drawRect(field.boundingBox, paint);
        }
    
        var picture = recorder.endRecording();
        return picture.toImage(_backgroundImage.width, _backgroundImage.height);
      }
    
      ///
      ///
      ///
      Future<void> _loadImageBackground(Uint8List imageBytes) async {
        if (imageBytes != null) {
          _backgroundImage = await _getImageFromBytes(imageBytes);
        } else {
          return null;
        }
      }
    
      ///
      ///
      ///
      Future<ui.Image> _getImageFromBytes(Uint8List imageBytes) async {
        var completer = Completer<ui.Image>();
        ui.decodeImageFromList(imageBytes, (image) {
          completer.complete(image);
        });
    
        return completer.future;
      }
    }
    
    

    Here is the result:

    enter image description here

    As you can see the rectangles are drawn perfectly fine, however, the image in the background is not visible. Is there something else I should be doing to draw the image, or is there another way to do this?

    Thanks!

  • Stanley
    Stanley almost 2 years
    Not work on flutter web