397 lines
14 KiB
Dart
397 lines
14 KiB
Dart
import 'dart:async';
|
||
import 'dart:io';
|
||
|
||
import 'package:cached_network_image/cached_network_image.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||
import 'package:flutter_native_image/flutter_native_image.dart';
|
||
import 'package:image_cropper/image_cropper.dart';
|
||
import 'package:image_picker/image_picker.dart';
|
||
import 'package:ironsource_mediation/ironsource_mediation.dart';
|
||
|
||
import '../../common/EventBusUtil.dart';
|
||
import '../../common/Global.dart';
|
||
import '../../common/TabUnderLine.dart';
|
||
import '../../common/app_util.dart';
|
||
import '../../common/dialog_bean.dart';
|
||
import '../../common/dialog_manager.dart';
|
||
import '../../common/dialog_util.dart';
|
||
import '../../common/func.dart';
|
||
import '../../dialog/invitation_code_dialog.dart';
|
||
import '../../dialog/login_dialog.dart';
|
||
import '../../dialog/phone_login_dialog.dart';
|
||
import '../../generated/l10n.dart';
|
||
import '../../network/NetworkConfig.dart';
|
||
import '../create/create_model.dart';
|
||
|
||
///上传
|
||
class UploadPage extends StatefulWidget {
|
||
const UploadPage({Key? key}) : super(key: key);
|
||
|
||
@override
|
||
State<UploadPage> createState() => _MePageState();
|
||
}
|
||
|
||
class _MePageState extends State<UploadPage> with SingleTickerProviderStateMixin {
|
||
StreamSubscription? subscription;
|
||
final CreateModel _viewModel = CreateModel();
|
||
GlobalKey<LoginDialogState> loginDialogKey = GlobalKey(); //登录弹框key
|
||
CroppedFile? selectImage; //选择的相册图
|
||
int currentSizeIndex = 0; //当前尺寸下标
|
||
String initImg = ""; //参考图
|
||
var imageValue = false;
|
||
|
||
Future<void> _createPic() async {
|
||
EasyLoading.show(status: 'loading...');
|
||
_viewModel.uploadImg(initImg);
|
||
_viewModel.getUserData();
|
||
}
|
||
|
||
@override
|
||
void initState() {
|
||
// TODO: implement initState
|
||
super.initState();
|
||
|
||
///网络请求回调
|
||
subscription = _viewModel.streamController.stream.listen((newData) {
|
||
String code = newData['code'];
|
||
EasyLoading.dismiss();
|
||
if (code.isNotEmpty) {
|
||
switch (code) {
|
||
case "uploadOk": //上传成功
|
||
EasyLoading.showToast(S().Upload_successful);
|
||
selectImage = null;
|
||
break;
|
||
|
||
case "uploadNo": //上传失败
|
||
String message = newData['data'];
|
||
EasyLoading.showToast(message);
|
||
selectImage = null;
|
||
break;
|
||
default:
|
||
String message = newData['data'];
|
||
EasyLoading.showToast(message);
|
||
break;
|
||
}
|
||
}
|
||
setState(() {});
|
||
});
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
// TODO: implement dispose
|
||
subscription?.cancel();
|
||
super.dispose();
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
final size = MediaQuery.of(context).size;
|
||
final h270 = size.width / 1.333333333;
|
||
final t70 = size.width / 5.1428571428571;
|
||
final w60 = size.width / 6;
|
||
final l85 = size.width / 4.235294117647;
|
||
final t35 = size.width / 10.285714285714;
|
||
final h340 = size.width / 1.0588235294117;
|
||
final t40 = size.width / 9;
|
||
final w90 = size.width / 4;
|
||
final h45 = size.width / 8;
|
||
final w150 = size.width / 2.4;
|
||
final h140 = size.width / 2.5714285714285;
|
||
final h60 = size.width / 6;
|
||
final h80 = size.width / 4.5;
|
||
|
||
return Scaffold(
|
||
backgroundColor: Colors.white,
|
||
body: Stack(
|
||
children: [
|
||
const Image(
|
||
width: double.infinity,
|
||
fit: BoxFit.fitWidth,
|
||
image: AssetImage('assets/images/upbg.webp'),
|
||
),
|
||
Column(
|
||
children: [
|
||
GestureDetector(
|
||
onTap: () async {
|
||
XFile img = await AppUtil.getImages();
|
||
selectImage = await AppUtil.cropImage(img.path, currentSizeIndex);
|
||
|
||
setState(() {});
|
||
},
|
||
child: Container(
|
||
margin: const EdgeInsets.only(top: 100, left: 60, right: 60),
|
||
child: selectImage != null
|
||
? Image.file(
|
||
File(selectImage!.path),
|
||
fit: BoxFit.cover,
|
||
)
|
||
: const Image(
|
||
width: double.infinity,
|
||
fit: BoxFit.fitWidth,
|
||
image: AssetImage('assets/images/kuang.png'),
|
||
),
|
||
)),
|
||
Container(
|
||
margin: const EdgeInsets.only(top: 20, left: 20, right: 20),
|
||
child: Text(
|
||
S.of(context).Upload_gallery,
|
||
style: const TextStyle(color: Color(0xFF000000), fontSize: 14),
|
||
),
|
||
),
|
||
GestureDetector(
|
||
onTap: () async {
|
||
_generateImages();
|
||
},
|
||
child: Container(
|
||
height: 50,
|
||
margin: const EdgeInsets.only(top: 20, left: 50, right: 50),
|
||
width: double.infinity,
|
||
alignment: Alignment.center,
|
||
decoration: const BoxDecoration(
|
||
gradient: LinearGradient(
|
||
begin: Alignment.centerLeft, //渐变开始于上面的中间开始
|
||
end: Alignment.centerRight, //渐变结束于下面的中间
|
||
colors: [Color(0xFF808EEF), Color(0xFFBE6FDF)]),
|
||
borderRadius: BorderRadius.all(Radius.circular(25))),
|
||
child: Text(
|
||
S.of(context).Confirm_submission,
|
||
style: const TextStyle(color: Color(0xFFFFFFFF), fontSize: 18),
|
||
),
|
||
))
|
||
],
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
///生成图片
|
||
_generateImages() async {
|
||
if (NetworkConfig.userId != "") {
|
||
if (selectImage != null) {
|
||
//处理图片
|
||
initImg = await _compressPictures();
|
||
|
||
///图生图
|
||
_createPic();
|
||
}
|
||
} else {
|
||
showLoginDialog();
|
||
}
|
||
}
|
||
|
||
//处理图片
|
||
_compressPictures() async {
|
||
String img = "";
|
||
//1,取方向,判断原图方向横竖
|
||
// 2,同方向取宽高中最大值,匹配已选择的画面比例宽高值。反方向小值
|
||
|
||
//1:1 512*512 3:4 512*704 4:3 704*512 9:16 512*910 16:9 910*512
|
||
File file = File(selectImage!.path);
|
||
File? compressedFile;
|
||
ImageProperties properties = await FlutterNativeImage.getImageProperties(file.path);
|
||
//判断当前方向
|
||
int isDirection = 0; //0 正方形 1 横向长方形 2 纵向长方形
|
||
if (properties.width == properties.height) {
|
||
isDirection = 0;
|
||
} else if (properties.width! > properties.height!) {
|
||
isDirection = 1;
|
||
} else if (properties.width! < properties.height!) {
|
||
isDirection = 2;
|
||
}
|
||
//下标选择方向
|
||
if (currentSizeIndex == 0) {
|
||
if (isDirection == 0) {
|
||
//如果大于512的正方形直接换比例成512,否则使用原图
|
||
if (properties.width! > 512) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path, quality: 100, targetWidth: 512, targetHeight: 512);
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
} else if (isDirection == 1) {
|
||
if (properties.width! > 512) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path,
|
||
quality: 100, targetWidth: 512, targetHeight: (properties.height! * 512 / properties.width!).round());
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
} else if (isDirection == 2) {
|
||
if (properties.height! > 512) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path,
|
||
quality: 100, targetWidth: (properties.width! * 512 / properties.height!).round(), targetHeight: 512);
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
}
|
||
} else if (currentSizeIndex == 1) {
|
||
//下标方向为纵向
|
||
if (isDirection == 0) {
|
||
//如果大于512的正方形直接换比例成512,否则使用原图
|
||
if (properties.width! > 512) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path, quality: 100, targetWidth: 512, targetHeight: 512);
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
} else if (isDirection == 1) {
|
||
//横向
|
||
if (properties.width! > 512) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path,
|
||
quality: 100, targetWidth: 512, targetHeight: (properties.height! * 512 / properties.width!).round());
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
} else if (isDirection == 2) {
|
||
//纵向
|
||
if (properties.height! > 704) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path,
|
||
quality: 100, targetWidth: (properties.width! * 704 / properties.height!).round(), targetHeight: 704);
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
}
|
||
} else if (currentSizeIndex == 2) {
|
||
//下标方向为横向
|
||
if (isDirection == 0) {
|
||
//如果大于512的正方形直接换比例成512,否则使用原图
|
||
if (properties.height! > 512) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path, quality: 100, targetWidth: 512, targetHeight: 512);
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
} else if (isDirection == 1) {
|
||
//横向
|
||
if (properties.width! > 704) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path,
|
||
quality: 100, targetWidth: 704, targetHeight: (properties.height! * 704 / properties.width!).round());
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
} else if (isDirection == 2) {
|
||
//纵向
|
||
if (properties.height! > 512) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path,
|
||
quality: 100, targetWidth: (properties.width! * 512 / properties.height!).round(), targetHeight: 512);
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
}
|
||
} else if (currentSizeIndex == 3) {
|
||
//下标方向为纵向
|
||
if (isDirection == 0) {
|
||
//如果大于512的正方形直接换比例成512,否则使用原图
|
||
if (properties.width! > 512) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path, quality: 100, targetWidth: 512, targetHeight: 512);
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
} else if (isDirection == 1) {
|
||
//横向
|
||
if (properties.width! > 512) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path,
|
||
quality: 100, targetWidth: 512, targetHeight: (properties.height! * 512 / properties.width!).round());
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
} else if (isDirection == 2) {
|
||
//纵向
|
||
if (properties.height! > 910) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path,
|
||
quality: 100, targetWidth: (properties.width! * 910 / properties.height!).round(), targetHeight: 910);
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
}
|
||
} else if (currentSizeIndex == 4) {
|
||
//下标方向为横向
|
||
if (isDirection == 0) {
|
||
//如果大于512的正方形直接换比例成512,否则使用原图
|
||
if (properties.height! > 512) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path, quality: 100, targetWidth: 512, targetHeight: 512);
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
} else if (isDirection == 1) {
|
||
//横向
|
||
if (properties.width! > 910) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path,
|
||
quality: 100, targetWidth: 910, targetHeight: (properties.height! * 910 / properties.width!).round());
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
} else if (isDirection == 2) {
|
||
//纵向
|
||
if (properties.height! > 512) {
|
||
compressedFile = await FlutterNativeImage.compressImage(file.path,
|
||
quality: 100, targetWidth: (properties.width! * 512 / properties.height!).round(), targetHeight: 512);
|
||
} else {
|
||
compressedFile = file;
|
||
}
|
||
}
|
||
}
|
||
|
||
ImageProperties properties2 = await FlutterNativeImage.getImageProperties(compressedFile!.path);
|
||
print("ImageProperties===" + properties2.width.toString() + "*" + properties2.height.toString());
|
||
|
||
///判断图片大小
|
||
double size = AppUtil.getFileSizeDouble(bytes: compressedFile.lengthSync());
|
||
//取整 大于10m直接抛弃
|
||
var s = size.ceil();
|
||
if (s > 10) {
|
||
EasyLoading.showToast(S.of(context).Image_too_large);
|
||
} else {
|
||
//取整 大于1m直接压缩,小于1m使用原图
|
||
if (s > 1) {
|
||
//图片压缩,压缩算法为 (10-s)*10,m越大调整后百分比越小
|
||
int percentage = (10 - s) * 10;
|
||
File compressedFile2 = await FlutterNativeImage.compressImage(compressedFile.path, quality: 80, percentage: percentage);
|
||
//AppUtil.getFileSizeDouble(bytes: compressedFile2.lengthSync());
|
||
img = await AppUtil.uploadImage2(compressedFile2);
|
||
} else {
|
||
//不压
|
||
img = await AppUtil.uploadImage2(compressedFile);
|
||
}
|
||
}
|
||
return img;
|
||
}
|
||
|
||
//弹出登录
|
||
showLoginDialog() {
|
||
DialogManager()
|
||
..add(DialogBean(
|
||
dialogPriority: DialogPriority.highClear,
|
||
createDialogWidget: () => DialogUtil.createTipWidget(
|
||
context,
|
||
LoginDialog(
|
||
loginDialogKey,
|
||
onTap: (index) {
|
||
switch (index) {
|
||
case 0:
|
||
if (loginDialogKey.currentState != null) {
|
||
loginDialogKey.currentState!.Pop();
|
||
}
|
||
FunctionUtil.bottomSheetDialog(context, const PhoneLoginDialog());
|
||
break;
|
||
case 1: //谷歌登录
|
||
Map<String, String> map = {"googleLogin": "googleLogin"};
|
||
invokeNativeMethod("googleLogin", map);
|
||
break;
|
||
}
|
||
},
|
||
),
|
||
"LoginDialog",
|
||
canceled: true)))
|
||
..show(context);
|
||
}
|
||
|
||
// 获取原生的值
|
||
invokeNativeMethod(String method, Map<String, dynamic> map) async {
|
||
dynamic args;
|
||
try {
|
||
args = await Global.method.invokeMethod(method, map);
|
||
} on PlatformException catch (e) {}
|
||
}
|
||
}
|