Flutter 用户拍照+用户选择图片,并且裁剪后传给后台

前言
虽然现在Flutter关于裁剪图片的插件挺多,在经过一下午的踩坑后,发现了其中很多问题,在Pub上排名靠前的两个插件均有问题

在这里插入图片描述

image_crop问题是在于如果不嵌套在MaterilaApp当中,选择图片后,无法正常裁剪,而且会将原图片损坏,导致原图片也无法使用,真的恶心
simple_image_crop是因为由于近期刚更新了版本,我在下载了示例代码后,运行时直接报错,希望作者在之后能够修改一个这个Bug问题。

正文

接下来就进入正题了,给大家介绍亲测好用的插件image_cropper,首先给大家展示一下我使用的效果
在这里插入图片描述

Pub地址https://pub.dev/packages/image_cropper
注意:

该插件是配合着image_picker插件来使用的,image_picker是用来呼唤起用户的相机以及选择图片用的,具体可以去参考官方文档https://pub.dev/packages/image_picker

这个是我自己封装好的插件,只是把调用摄像头和裁剪的方法封装进去了,方便别的页面调用

import 'package:project/plugins/Plugins.dart';

在这里插入图片描述
这个是我封装的屏幕适配类,具体可参考我的另外一篇文章:https://blog.csdn.net/qq_38774121/article/details/102883746

import 'package:project/plugins/ScreenAdapter.dart';

这个是我封装的统一请求接口类,用来发送上传图片请求的,具体可参考我的另外一篇文章:https://blog.csdn.net/qq_38774121/article/details/102883746

import 'package:project/config/api.dart';
完整代码(具体的意思我全部写在代码当中了,如果有什么问题,请留言给我,24小时内答复您)
import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:project/plugins/Plugins.dart';				
import 'package:project/plugins/ScreenAdapter.dart';
import 'package:project/config/api.dart';


class ModifyUserInfo extends StatefulWidget {
 
  @override
  _ModifyUserInfoState createState() => _ModifyUserInfoState();
}

class _ModifyUserInfoState extends State<ModifyUserInfo> {
  
  File _file;
  var _croppFile;

  var api = Api();

  var imageUrl = 'https://huyaimg.msstatic.com/avatar/1084/37/7c96090110880e88916b11e4a18cf9_180_135.jpg?437764';						// 初始化默认图片



  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Container(
            child: Text('测试页面'),
          ),
        ),
        body: ConstrainedBox(
          constraints: BoxConstraints.expand(),
          child: Container(
            color: Color.fromRGBO(233, 233, 233, 0.7),
            child: ListView(
              children: <Widget>[
                InkWell(
                  child: Container(
                    padding: EdgeInsets.symmetric(
                        horizontal: ScreenAdapter.setWidth(20)),
                    color: Colors.white,
                    height: ScreenAdapter.setHeight(150),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: <Widget>[
                        Text(
                          '头像',
                          style: TextStyle(
                              fontWeight: FontWeight.bold,
                              fontSize: ScreenAdapter.size(28)),
                        ),
                        Row(
                          children: <Widget>[
                            CircleAvatar(
                              backgroundImage: NetworkImage(imageUrl),
                              radius: 40.0,
                            ),
                            Icon(Icons.chevron_right)
                          ],
                        ),
                      ],
                    ),
                  ),
                  onTap: showSelectPicker,
                ),
                UserInfoList('昵称', '磐石Boy'),
                // Text('')
                _croppFile != null ? Image.file(_croppFile) : Text('')
              ],
            ),
          ),
        ));
  }

  // 选择图片
  showSelectPicker() {
    showModalBottomSheet(
      context: context,
      builder: (context){
        return Container(
          height: ScreenAdapter.setHeight(200),
          child: Column(
            children: <Widget>[
              InkWell(
                onTap: () async {
                  var file = await Plugins.takePhoto();
                  if(file!=null){
                    // 获取图片路径
                    setState(() {
                      _file = file;
                    });
                    // 关闭弹窗
                    Navigator.pop(context);
                    // 获取裁剪后地址
                    
                    var croppFile = await Plugins.cropImage(context, file.path);
                    // 请求接口上传图片
                    if(croppFile!=null){
                      api.postData('uploadFile', formData: await FormData1(croppFile.path)).then((val){
                        var imgurl = json.decode(val.toString());
                        setState(() {
                          imageUrl = 'https://flutter.ikuer.cn/'+imgurl['file_path'];
                        });
                      });
                      setState(() {
                        _croppFile = croppFile;
                      });
                    }
                  }
                  
                },
                child: Container(
                  alignment: Alignment.center,
                  height: ScreenAdapter.setHeight(100),
                  child: Text('拍照'),
                  decoration: BoxDecoration(
                    border: Border(
                      bottom: BorderSide(
                        width: 0.5,
                        color: Colors.black26
                      )
                    )
                  ),
                ),
              ),
              InkWell(
                onTap: ()  async {
                  var file = await Plugins.openGallery();
                  if(file!=null){
                    setState(() {
                      _file = file;
                    });
                    Navigator.pop(context);
                    var croppFile = await Plugins.cropImage(context, file.path);
                    if(croppFile!=null){
                      api.postData('uploadFile', formData: await FormData1(croppFile.path)).then((val){
                        var imgurl = json.decode(val.toString());
                        setState(() {
                          imageUrl = 'https://flutter.ikuer.cn/'+imgurl['file_path'];
                        });
                      });
                      setState(() {
                        _croppFile = croppFile;
                      });
                    }
                  }
                },
                child: Container(
                  alignment: Alignment.center,
                  height: ScreenAdapter.setHeight(100),
                  child: Text('相册选择'),
                ),
              )
            ],
          )
        );
      }
    );
  }

 // dio上传文件FormData格式
  Future<FormData> FormData1(fileUrl) async {
    return FormData.fromMap({
      "file": await MultipartFile.fromFile(fileUrl)
    });
  }

  // 用户信息列表
  Widget UserInfoList(String title, String subtitle) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: ScreenAdapter.setWidth(20)),
      color: Colors.white,
      height: ScreenAdapter.setHeight(150),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Text(
            '${title}',
            style: TextStyle(
                fontWeight: FontWeight.bold, fontSize: ScreenAdapter.size(28)),
          ),
          Row(
            children: <Widget>[Text('${subtitle}'), Icon(Icons.chevron_right)],
          )
        ],
      ),
    );
  }
}

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值