Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I draw a image with circular border in canvas?

I am currently working with canvas in Flutter for the first time. I have to do an market for google maps (its just possible to do it using canvas or raw images for now), using a custom image taken from the internet. I got something working with the image and it looks like this:

Current result

But my expected result should have the image with a circular shape. It looks like this:

Expected result


Does someone know how to do it?


Here some code

Painter

class ImageEditor extends CustomPainter {
  ImageEditor({
    this.image,
  });

  ui.Image image;

  @override
  void paint(Canvas canvas, Size size) async{
    canvas.drawImage(image, new Offset(0, -size.height*0.8), new Paint()..style=PaintingStyle.fill);

    final radius = math.min(size.width, size.height) / 8;
    final center = Offset(50, 50);
    Paint paintCircle = Paint()..color = Colors.black;
    Paint paintBorder = Paint()
      ..color = Colors.white
      ..strokeWidth = size.width/36
      ..style = PaintingStyle.stroke;
    canvas.drawCircle(center, radius, paintCircle);
    canvas.drawCircle(center, radius, paintBorder);
  }

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

Main class

import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import 'package:flutter/services.dart' show rootBundle;
import 'dart:async';
import 'dart:typed_data';

import 'package:flutter_cache_manager/flutter_cache_manager.dart';

import 'canvas_test.dart';

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 {
    image = await _loadImage("https://<link>");
  }

  Future<ui.Image> _loadImage(String photoUrl) async {
    final cache = DefaultCacheManager();
    final file = await cache.getSingleFile(photoUrl);
    final bytes = new Uint8List.fromList(await file.readAsBytes());

    final Completer<ui.Image> completer = new Completer();
    ui.decodeImageFromList(bytes, (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 Scaffold(
      appBar: AppBar(
        title: Text("First Canvas"),
      ),
      body: Container(
        color: Colors.blueGrey,
        child: Center(
          child: Container(
            width: 80,
            height: 90.0,
            child:  _buildImage(),
            ),
          ),
        ),
      );
  }
}
like image 439
Javier Benitez Avatar asked Jun 21 '19 09:06

Javier Benitez


1 Answers

    @override
    void paint(Canvas canvas, Size size) async{
      final center = Offset(50, 50);
      final radius = math.min(size.width, size.height) / 8;

      // The circle should be paint before or it will be hidden by the path 
      Paint paintCircle = Paint()..color = Colors.black;
      Paint paintBorder = Paint()
        ..color = Colors.white
        ..strokeWidth = size.width/36
        ..style = PaintingStyle.stroke;
      canvas.drawCircle(center, radius, paintCircle);
      canvas.drawCircle(center, radius, paintBorder);

      var drawImageWidth = 0;
      var drawImageHeight = -size.height*0.8;

      Path path = Path()
        ..addOval(Rect.fromLTWH(drawImageWidth, drawImageHeight, image.width, image.height));

      canvas.clipPath(path);

      canvas.drawImage(image, new Offset(drawImageWidth, drawImageHeight), new Paint());

    }

This solution allows you to make round image on the canvas.

like image 134
Andrey Turkovsky Avatar answered Nov 13 '22 20:11

Andrey Turkovsky