FlutterFlutter相关

Flutter——头像上传功能,实现照片选择及裁剪

2020-02-15  本文已影响0人  小宇宙_fly

使用两个开发库,image_picker和image_crop。

前者用来拍照或者从相册选择照片,后者用来裁剪,结果均为File类型,裁剪完成后可以直接上传文件。

先写到这儿,有时间上代码。

更新:

实现的功能是点击头像图片,弹出选择框,选择拍照或者从相册中选取:

选择头像上传方式

拍照或选取一张图片后,裁剪到想要大小。进行保存或者上传。

实现:

首先的首先,在Android的manifest文件中,加入网络、相机、文件读写的权限,并在application中加入一个activity声明。

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<activity
            android:name="com.yalantis.ucrop.UCropActivity"
            android:screenOrientation="portrait"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>

首先在yaml文件中添加依赖:上https://pub.dartlang.org/packages/ flutter第三方插件官网,找最新版即可。添加之后 package get。

在调用的文件导入包,

import 'package:image_picker/image_picker.dart';

点击按钮,进行拍照:

///拍摄照片
Future getImage() async {
  await ImagePicker.pickImage(source: ImageSource.camera)
      .then((image) => cropImage(image));
}

通过相册选取:

///从相册选取
Future chooseImage() async {
  await ImagePicker.pickImage(source: ImageSource.gallery)
      .then((image) => cropImage(image));
}

.then拿到的是拍好的照片,之后进行跳转到剪裁页面CropImageRoute 进行剪裁。

void cropImage(File originalImage) async {
  String result = await Navigator.push(context,
      MaterialPageRoute(builder: (context) => CropImageRoute(originalImage)));
  if (result.isEmpty) {
    print('上传失败');
  } else {
    //result是图片上传后拿到的url
    setState(() {
      iconUrl = result;
      print('上传成功:$iconUrl');
      _upgradeRemoteInfo();//后续数据处理,这里是更新头像信息
    });
  }
}

剪裁页面CropImageRoute 代码:

import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_productapp/home/moudel/upload_result.dart';
import 'package:flutter_productapp/home/util/screen.dart';
import 'package:flutter_productapp/base_ui/themes.dart';
import 'package:image_crop/image_crop.dart';

class CropImageRoute extends StatefulWidget {
  CropImageRoute(this.image);

  File image; //原始图片路径

  @override
  _CropImageRouteState createState() => new _CropImageRouteState();
}

class _CropImageRouteState extends State<CropImageRoute> {
  double baseLeft; //图片左上角的x坐标
  double baseTop; //图片左上角的y坐标
  double imageWidth; //图片宽度,缩放后会变化
  double imageScale = 1; //图片缩放比例
  Image imageView;
  final cropKey = GlobalKey<CropState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Container(
      height: Screen.height,
      width: Screen.width,
      color: ThemeColors.color333333,
      child: Column(
        children: <Widget>[
          Container(
            height: Screen.height * 0.8,
            child: Crop.file(
              widget.image,
              key: cropKey,
              aspectRatio: 1.0,
              alwaysShowGrid: true,
            ),
          ),
          RaisedButton(
            onPressed: () {
              _crop(widget.image);
            },
            child: Text('ok'),
          ),
        ],
      ),
    ));
  }

  Future<void> _crop(File originalFile) async {
    final crop = cropKey.currentState;
    final area = crop.area;
    if (area == null) {
      //裁剪结果为空
      print('裁剪不成功');
    }
    await ImageCrop.requestPermissions().then((value) {
      if (value) {
        ImageCrop.cropImage(
          file: originalFile,
          area: crop.area,
        ).then((value) {
          upload(value);
        }).catchError(() {
          print('裁剪不成功');
        });
      } else {
        upload(originalFile);
      }
    });
  }

  ///上传头像
  void upload(File file) {
    print(file.path);
    Dio dio = Dio();
    dio
        .post("http://your ip:port/",
            data: FormData.from({'file': file}))
        .then((response) {
      if (!mounted) {
        return;
      }
      //处理上传结果
      UploadIconResult bean = UploadIconResult(response.data);
      print('上传头像结果 $bean');
      if (bean.code == '1') {
        Navigator.pop(context, bean.data.url);//这里的url在上一页调用的result可以拿到
      } else {
        Navigator.pop(context, '');
      }
    });
  }
}

————————————————

原文链接:https://blog.csdn.net/NNadn/article/details/90633053

上一篇下一篇

猜你喜欢

热点阅读