【问题标题】:How can I draw a image with circular border in canvas?如何在画布中绘制带有圆形边框的图像?
【发布时间】:2019-11-04 03:19:30
【问题描述】:

我目前是第一次在 Flutter 中使用画布。我必须使用从互联网上获取的自定义图像谷歌地图市场目前只能使用画布或原始图像)。我得到了一些处理图像的东西,它看起来像这样:

但我的预期结果应该是圆形的图像。它看起来像这样:




有人知道怎么做吗?


这里有一些代码

画家

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;
  }
}

主类

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(),
            ),
          ),
        ),
      );
  }
}

【问题讨论】:

  • 您可以将照片从下面的圆圈中分离出来,然后让您的照片变成圆形(使用CircleAvatarClipper
  • 不要创建自定义 Painter - 使用 ClipRRect 小部件。请参阅this answer 了解有关圆形小部件最佳实践的更多信息。
  • @AndreyTurkovsky 和 ​​George 无法将小部件用于谷歌地图标记。如果不是,使用 ClipperCircleAvatar 会很简单。

标签: canvas flutter google-maps-markers


【解决方案1】:
    @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());

    }

此解决方案允许您在canvas 上制作圆形图像。

【讨论】:

  • 谢谢!它部分有效,它删除了边框,但也删除了黑点。你知道为什么会发生这种情况吗?
  • 可能这个..addOval(Rect.fromCircle(center, radius)) 没有正确定位。第二个椭圆必须覆盖黑点,所以它似乎在错误的位置。为整个画布设置彩色背景,您可以看到第二个椭圆的确切位置
  • 也许第二个椭圆的半径必须更大
  • 我能够修复它。我删除了..addOval(Rect.fromCircle(center, radius)) 并更改了绘图顺序。我发现顺序会影响元素是否隐藏。我用这些修改改变了你的答案。我希望你不要介意。检查它是否适合您
  • 在剪裁之前先涂漆 - 是的,很好的解决方案,我没有考虑过。
猜你喜欢
  • 2017-10-31
  • 1970-01-01
  • 2023-04-03
  • 2015-01-08
  • 2015-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多