Flutter 在图像顶部添加文本并通过点击按钮共享图像

Flutter 在图像顶部添加文本并通过点击按钮共享图像,flutter,dart,Flutter,Dart,我一直在尝试在图像顶部添加文本,然后允许用户共享图像。我有两个问题似乎无法解决 添加到画布时,文本从屏幕溢出,未在TextPainter中环绕 我一直在尝试使用FloatingActionButton共享图像。我遇到的问题是共享实际图像而不是图像字符串。我一直在使用该软件包尝试实现它,但我得到了一个错误。我真的只想分享我写在上面的文字的图片 未处理的异常:“Image”类型不是“String”类型的子类型 非常感谢您的帮助 import 'dart:typed_data'; import 'd

我一直在尝试在图像顶部添加文本,然后允许用户共享图像。我有两个问题似乎无法解决

  • 添加到画布时,文本从屏幕溢出,未在TextPainter中环绕

  • 我一直在尝试使用FloatingActionButton共享图像。我遇到的问题是共享实际图像而不是图像字符串。我一直在使用该软件包尝试实现它,但我得到了一个错误。我真的只想分享我写在上面的文字的图片

  • 未处理的异常:“Image”类型不是“String”类型的子类型

    非常感谢您的帮助

    import 'dart:typed_data';
    import 'dart:ui' as ui;
    import 'package:flutter/material.dart';
    import 'dart:io';
    import 'package:esys_flutter_share/esys_flutter_share.dart';
    import 'package:flutter/services.dart' show rootBundle;
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      var _imageUrl = 'https://imageurl.png';
      var _img;
      var nimg;
    
      @override
      void initState() {
    
        _showImg();
    
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        var widget =
        _img != null ? Image.memory(_img) : Text('pleace click button');
        return Scaffold(
          appBar: AppBar(),
          body: Center(child: widget),
          floatingActionButton: FloatingActionButton(
            onPressed: () async {
    
              final ByteData bytes = await rootBundle.load(nimg);
              await Share.file('esys image', '$nimg', bytes.buffer.asUint8List(), 'image/png');
    
            },
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    
    
      _showImg() async{
        var uri = Uri.parse(_imageUrl);
        var httpClient = HttpClient();
        var request = await httpClient.getUrl(uri);
        var response = await request.close();
        var imageData = <int>[];
        await response.forEach((data) async {
          imageData.addAll(data);
        });
    
        ui.Image image =
            await decodeImageFromList(Uint8List.fromList(imageData));
        var pictureRecorder = ui.PictureRecorder();
        var canvas = Canvas(pictureRecorder);
        var paint = Paint();
        paint.isAntiAlias = true;
    
        var src = Rect.fromLTWH(
            0.0, 0.0, image.width.toDouble(), image.height.toDouble());
        var dst = Rect.fromLTWH(
            0.0, 0.0, image.width.toDouble(), image.height.toDouble());
        canvas.drawRect(Rect.fromLTWH(0.0, 0.0, 200.0, 200.0), paint);
        canvas.drawImageRect(image, src, dst, paint);
    
    
        //Add text on image
        TextSpan span = new TextSpan(
            style: new TextStyle(color: Colors.white, fontSize: 150.0,
                fontFamily: 'Roboto'), text: "Here is some great text to put on top");
        TextPainter tp = new TextPainter(
            text: span, textDirection: TextDirection.ltr, textAlign: TextAlign.center);
        tp.layout();
        tp.paint(canvas, new Offset(image.width/2 - image.width/2 /2, image.height/2 - image.height/2 /3));
    
    
        var pic = pictureRecorder.endRecording();
        ui.Image img = await pic.toImage(image.width, image.height);
        var byteData = await img.toByteData(format: ui.ImageByteFormat.png);
        var buffer = byteData.buffer.asUint8List();
    
        //Assign image to be shared
        nimg = img;
    
        //Set the image as the child in the body
        setState(() {
          _img = buffer;
        });
      }
    
    }
    
    导入'dart:typed_data';
    将“dart:ui”导入为ui;
    进口“包装:颤振/材料.省道”;
    导入“dart:io”;
    导入“包:esys_flatter_share/esys_flatter_share.dart”;
    导入“包:flatter/services.dart”显示根包;
    void main()=>runApp(MyApp());
    类MyApp扩展了无状态小部件{
    //此小部件是应用程序的根。
    @凌驾
    小部件构建(构建上下文){
    返回材料PP(
    标题:“颤振演示”,
    主题:主题数据(
    主样本:颜色。蓝色,
    ),
    主页:MyHomePage(标题:“颤振演示主页”),
    );
    }
    }
    类MyHomePage扩展StatefulWidget{
    MyHomePage({Key,this.title}):超级(Key:Key);
    最后的字符串标题;
    @凌驾
    _MyHomePageState createState()=>\u MyHomePageState();
    }
    类_MyHomePageState扩展状态{
    var\u imageUrl=https://imageurl.png';
    var_img;
    var nimg;
    @凌驾
    void initState(){
    _showImg();
    super.initState();
    }
    @凌驾
    小部件构建(构建上下文){
    变量小部件=
    _img!=null?Image.memory(_img):文本('pleace click button');
    返回脚手架(
    appBar:appBar(),
    主体:中心(子:小部件),
    浮动操作按钮:浮动操作按钮(
    onPressed:()异步{
    final ByteData bytes=等待rootBundle.load(nimg);
    等待Share.file('esys image','$nimg',bytes.buffer.asUint8List(),'image/png');
    },
    工具提示:“增量”,
    子:图标(Icons.add),
    ),//此尾随逗号使生成方法的自动格式设置更方便。
    );
    }
    _showImg()异步{
    var uri=uri.parse(_imageUrl);
    var httpClient=httpClient();
    var request=wait-httpClient.getUrl(uri);
    var response=wait request.close();
    var imageData=[];
    等待响应。forEach((数据)异步{
    imageData.addAll(数据);
    });
    图像=
    等待解码ImageFromList(Uint8List.fromList(imageData));
    var pictureRecorder=ui.pictureRecorder();
    var canvas=画布(pictureRecorder);
    var paint=paint();
    paint.Isatarias=真;
    var src=Rect.fromLTWH(
    0.0,0.0,image.width.toDouble(),image.height.toDouble());
    var dst=Rect.fromLTWH(
    0.0,0.0,image.width.toDouble(),image.height.toDouble());
    canvas.drawRect(Rect.fromLTWH(0.0,0.0,200.0,200.0),paint);
    canvas.drawImageRect(图像、src、dst、绘制);
    //在图像上添加文本
    TextSpan=新TextSpan(
    样式:新文本样式(颜色:Colors.white,fontSize:150.0,
    fontFamily:‘Roboto’、文字:“这里有一些很棒的文字放在上面”);
    TextPainter tp=新的TextPainter(
    text:span,textDirection:textDirection.ltr,textAlign:textAlign.center);
    tp.layout();
    tp.paint(画布,新偏移量(image.width/2-image.width/2/2,image.height/2-image.height/2/3));
    var pic=pictureRecorder.endRecording();
    ui.Image img=wait pic.toImage(Image.width,Image.height);
    var byteData=wait img.toByteData(格式:ui.ImageByteFormat.png);
    var buffer=byteData.buffer.asUint8List();
    //分配要共享的图像
    nimg=img;
    //将图像设置为主体中的子对象
    设置状态(){
    _img=缓冲区;
    });
    }
    }
    
    esys\u flatter\u share
    无法同时共享这两种数据类型。我已经遇到了这个问题,通过在代码中使用这个包并编辑它的方法来修复它,从而允许我们共享这两种数据类型。这是已编辑的包文件

    如何以本地代码获取包

    结帐答案


    更新后的代码url为,请下载并按照上面的答案进行操作。

    用文本共享图像的最简单方法:

  • 创建一个堆栈并将图像放入其中,将文本小部件放置在图像上您想要的任何位置

  • 使用重绘边界包装堆栈

  • 截图

  • 与esys分享\u颤振\u分享
  • 当然,你也可以使用软件包向图像中添加文本

    RenderRepaintBoundary boundary = _globalKey.currentContext.findRenderObject();
    Image image = await boundary.toImage();