Image 颤振:在图像上过度输出图像将其保存在图像上,然后共享

Image 颤振:在图像上过度输出图像将其保存在图像上,然后共享,image,flutter,camera,photo,Image,Flutter,Camera,Photo,我想在gallery/camera的图像上添加一个简单的图像。行为应该是这样的 打开应用程序,选择一张照片或使用浮动按钮制作一张照片,然后显示图像并将我们的徽标覆盖在左下角。现在一切都好了 然后我想在一张图片中保存这两张图片,但我不知道这个过程是如何调用的,也不知道如何实现它 import 'package:share/share.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget {

我想在gallery/camera的图像上添加一个简单的图像。行为应该是这样的

打开应用程序,选择一张照片或使用浮动按钮制作一张照片,然后显示图像并将我们的徽标覆盖在左下角。现在一切都好了

然后我想在一张图片中保存这两张图片,但我不知道这个过程是如何调用的,也不知道如何实现它

import 'package:share/share.dart';
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Image Picker Demo',
      home: MyHomePage(title: 'Image Picker Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  File _imageFile;
  dynamic _pickImageError;
  String _retrieveDataError;

  void _onImageButtonPressed(ImageSource source) async {
    try {
      _imageFile = await ImagePicker.pickImage(source: source);
    } catch (e) {
      _pickImageError = e;
    }
    setState(() {});
  }

  Widget _previewImage() {
    final Text retrieveError = _getRetrieveErrorWidget();
    if (retrieveError != null) {
      return retrieveError;
    }
    if (_imageFile != null) {
      print('La imagen ha sido puesta en la pantalla?');
      return Image.file(_imageFile);
    } else if (_pickImageError != null) {
      return Text(
        'Pick image error: $_pickImageError',
        textAlign: TextAlign.center,
      );
    } else {
      return const Text(
        'You have not yet picked an image.',
        textAlign: TextAlign.center,
      );
    }
  }

  Future<void> retrieveLostData() async {
    final LostDataResponse response = await ImagePicker.retrieveLostData();
    if (response.isEmpty) {
      return;
    }
    if (response.file != null) {
      setState(() {
        _imageFile = response.file;
      });
    } else {
      _retrieveDataError = response.exception.code;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
          child: Center(
              child: Stack(children: <Widget>[
        Container(
            color: Colors.amber,
            child: Platform.isAndroid
                ? FutureBuilder<void>(
                    future: retrieveLostData(),
                    builder:
                        (BuildContext context, AsyncSnapshot<void> snapshot) {
                      switch (snapshot.connectionState) {
                        case ConnectionState.none:
                        case ConnectionState.waiting:
                          return const Text(
                            'You have not yet picked an image.',
                            textAlign: TextAlign.center,
                          );
                        case ConnectionState.done:
                          return _previewImage();
                        default:
                          if (snapshot.hasError) {
                            return Text(
                              'Pick image/video error: ${snapshot.error}}',
                              textAlign: TextAlign.center,
                            );
                          } else {
                            return const Text(
                              'You have not yet picked an image.',
                              textAlign: TextAlign.center,
                            );
                          }
                      }
                    },
                  )
                : (_previewImage())), //
        Positioned(
            bottom: 16,
            left: 16,
            width: 100,
            height: 100,
            child: Image.network(
                'http://father-home.ru/wp-content/uploads/2018/05/cropped-logo8.png'))
      ]))),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          FloatingActionButton(
            onPressed: () {
              _onImageButtonPressed(ImageSource.gallery);
            },
            heroTag: 'image0',
            tooltip: 'Pick Image from gallery',
            child: const Icon(Icons.photo_library),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 16.0),
            child: FloatingActionButton(
              onPressed: () {
                _onImageButtonPressed(ImageSource.camera);
              },
              heroTag: 'image1',
              tooltip: 'Take a Photo',
              child: const Icon(Icons.camera_alt),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 16.0),
            child: FloatingActionButton(
              onPressed: () {
                _onShare();
              },
              tooltip: 'Share',
              child: const Icon(Icons.share),
            ),
          ),
        ],
      ),
    );
  }

  void _onShare(){

//TODO: save the two images into one and share

  }

  Text _getRetrieveErrorWidget() {
    if (_retrieveDataError != null) {
      final Text result = Text(_retrieveDataError);
      _retrieveDataError = null;
      return result;
    }
    return null;
  }
}
导入“包:share/share.dart”; void main(){ runApp(MyApp()); } 类MyApp扩展了无状态小部件{ @凌驾 小部件构建(构建上下文){ 返回材料PP( 标题:“图像选择器演示”, 主页:MyHomePage(标题:“图像选择器示例”), ); } } 类MyHomePage扩展StatefulWidget{ MyHomePage({Key,this.title}):超级(Key:Key); 最后的字符串标题; @凌驾 _MyHomePageState createState()=>\u MyHomePageState(); } 类_MyHomePageState扩展状态{ 文件imageFile; 动态误差; 字符串_retrieveDataError; void _onImageButtonPressed(图像源)异步{ 试一试{ _imageFile=await ImagePicker.pickImage(源:源); }捕获(e){ _pickImageError=e; } setState((){}); } 小部件_previewImage(){ 最终文本检索错误=_getRetrieveErrorWidget(); 如果(retrieveError!=null){ 返回检索错误; } 如果(_imageFile!=null){ 印刷品(‘在潘塔拉的照片’); 返回Image.file(_imageFile); }else if(_pickImageError!=null){ 返回文本( '拾取图像错误:$\u pickImageError', textAlign:textAlign.center, ); }否则{ 返回常量文本( “您尚未选择图像。”, textAlign:textAlign.center, ); } } 未来的检索速度数据()异步{ 最终LostDataResponse响应=等待ImagePicker.retrieveLostData(); if(response.isEmpty){ 返回; } if(response.file!=null){ 设置状态(){ _imageFile=response.file; }); }否则{ _retrieveDataError=response.exception.code; } } @凌驾 小部件构建(构建上下文){ 返回脚手架( 正文:安全区( 儿童:中心( 子:堆栈(子:[ 容器( 颜色:颜色。琥珀色, 子:Platform.isAndroid ?未来建设者( future:retrieveLostData(), 建设者: (BuildContext上下文,异步快照){ 交换机(快照.连接状态){ 案例连接状态。无: 案例连接状态。正在等待: 返回常量文本( “您尚未选择图像。”, textAlign:textAlign.center, ); 案例连接状态。完成: 返回_previewImage(); 违约: if(snapshot.hasError){ 返回文本( '拾取图像/视频错误:${snapshot.error}}', textAlign:textAlign.center, ); }否则{ 返回常量文本( “您尚未选择图像。”, textAlign:textAlign.center, ); } } }, ) :(_previewImage())// 定位( 底图:16, 左:16, 宽度:100, 身高:100, 孩子:Image.network( 'http://father-home.ru/wp-content/uploads/2018/05/cropped-logo8.png')) ]))), floatingActionButton:列( mainAxisAlignment:mainAxisAlignment.end, 儿童:[ 浮动操作按钮( 已按下:(){ _OnImageButton按下(ImageSource.gallery); }, heroTag:'image0', 工具提示:“从库中拾取图像”, 子:常量图标(图标。照片库), ), 填充物( 填充:仅限常量边集(顶部:16.0), 子:浮动操作按钮( 已按下:(){ _OnImageButton按下(ImageSource.camera); }, heroTag:'image1', 工具提示:“拍照”, 子项:常量图标(Icons.camera_alt), ), ), 填充物( 填充:仅限常量边集(顶部:16.0), 子:浮动操作按钮( 已按下:(){ _onShare(); }, 工具提示:“共享”, 子:常量图标(Icons.share), ), ), ], ), ); } void _onShare(){ //TODO:将两个图像保存为一个并共享 } 文本_getRetrieveErrorWidget(){ 如果(_retrieveDataError!=null){ 最终文本结果=文本(\u retrieveDataError); _retrieveDataError=null; 返回结果; } 返回null; } } 具有以下代码的小部件如下所示:


您可以使用重新绘制边界小部件将特定小部件导出到图像。

您可以使用重新绘制边界小部件将特定小部件导出到图像。

我相信您需要使用位图

  • 加载2个位图,一个是背景,一个是您的徽标
  • 根据需要应用转换
  • 将输出位图保存到文件

  • 请看:

    我相信您需要使用位图

  • 加载2个位图,一个是背景,一个是您的徽标
  • 根据需要应用转换
  • 拯救