|
...
|
...
|
@@ -28,11 +28,13 @@ import 'package:provider/provider.dart'; |
|
|
|
import 'package:url_launcher/url_launcher.dart';
|
|
|
|
import 'package:crypto/crypto.dart';
|
|
|
|
import 'package:flutter_image_compress/flutter_image_compress.dart';
|
|
|
|
import 'dart:convert';
|
|
|
|
import 'package:webview_flutter/webview_flutter.dart';
|
|
|
|
|
|
|
|
import '../app.dart';
|
|
|
|
import 'package:http/http.dart' as http;
|
|
|
|
import 'package:image/image.dart' as IMG;
|
|
|
|
import 'dart:ui' as ui;
|
|
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
|
import 'package:image_cropper/image_cropper.dart';
|
|
|
|
// import 'dart:typed_data';
|
|
|
|
|
|
|
|
typedef BookTimeSetCallback = void Function(bool needChange);
|
|
|
|
|
|
...
|
...
|
@@ -1166,7 +1168,7 @@ class Utils { |
|
|
|
String _userName = "gh_487873d353b3";
|
|
|
|
String _path = "pack-cookbook/pages/index?rid=$rid&identity=2&sid=$sid";
|
|
|
|
String _description = "OneKey";
|
|
|
|
Uint8List source = await testComporessList(_thumbnail);
|
|
|
|
Uint8List source = await testComporessList(context, _thumbnail);
|
|
|
|
var model = new WeChatShareMiniProgramModel(
|
|
|
|
webPageUrl: _webPageUrl,
|
|
|
|
userName: _userName,
|
|
...
|
...
|
@@ -1200,7 +1202,7 @@ class Utils { |
|
|
|
String _path =
|
|
|
|
"pack-cookbook/pages/success?rid=$rid&identity=2&hasOnlyShow=1";
|
|
|
|
String _description = "OneKey";
|
|
|
|
Uint8List source = await testComporessList(_thumbnail);
|
|
|
|
Uint8List source = await testComporessList(context, _thumbnail);
|
|
|
|
var model = new WeChatShareMiniProgramModel(
|
|
|
|
webPageUrl: _webPageUrl,
|
|
|
|
userName: _userName,
|
|
...
|
...
|
@@ -1261,9 +1263,11 @@ class Utils { |
|
|
|
/// 下载图片
|
|
|
|
static downloadFile(String url) async {
|
|
|
|
// if (await Permission.storage.request().isGranted) {
|
|
|
|
|
|
|
|
var response = await Dio()
|
|
|
|
.get(url, options: Options(responseType: ResponseType.bytes));
|
|
|
|
Uint8List result = Uint8List.fromList(response.data);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
// print(result);
|
|
|
|
// if (result["isSuccess"]) {
|
|
...
|
...
|
@@ -1277,36 +1281,166 @@ class Utils { |
|
|
|
}
|
|
|
|
|
|
|
|
/// 图片压缩 Uint8List -> Uint8List
|
|
|
|
static Future<Uint8List> testComporessList(String url) async {
|
|
|
|
Uint8List result = await downloadFile(url);
|
|
|
|
if (result.length < 200 * 1024) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
var quality = 100;
|
|
|
|
if (result.length > 4 * 1024 * 1024) {
|
|
|
|
static Future<Uint8List> testComporessList(
|
|
|
|
BuildContext context, String url) async {
|
|
|
|
Loading.showLoading(context);
|
|
|
|
Uint8List list = await downloadFile(url); //下载图片
|
|
|
|
Uint8List result = await resizeImage(list); //重置图片尺寸
|
|
|
|
Uint8List resultnew = await realComporessList(result); //压缩图片
|
|
|
|
|
|
|
|
Loading.hideLoading(context);
|
|
|
|
return resultnew;
|
|
|
|
// if (result.length < 128 * 1024) {
|
|
|
|
// return result;
|
|
|
|
// } else {
|
|
|
|
// result = await realComporessList(result);
|
|
|
|
// return result;
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
static realComporessList(Uint8List list) async {
|
|
|
|
int minHeight = 457; // 指定最小分辨率的高度
|
|
|
|
int minWidth = 572; // 指定最小分辨率的宽度
|
|
|
|
int quality = imageQuality(list.length);
|
|
|
|
Uint8List result = await FlutterImageCompress.compressWithList(
|
|
|
|
list,
|
|
|
|
minWidth: minWidth,
|
|
|
|
minHeight: minHeight,
|
|
|
|
quality: quality,
|
|
|
|
);
|
|
|
|
debugPrint("压缩后图片的大小:${size(result.length)}");
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 根据传入的图片字节长度,返回指定的图片质量
|
|
|
|
static int imageQuality(int length) {
|
|
|
|
debugPrint("压缩前图片的大小:${size(length)}");
|
|
|
|
int quality = 100; // 图片质量指数
|
|
|
|
int m = 1024 * 1024; // 1 兆
|
|
|
|
if (length < 0.5 * m) {
|
|
|
|
quality = 70;
|
|
|
|
debugPrint("图片小于 0.5 兆,质量设置为 70");
|
|
|
|
} else if (length >= 0.5 * m && length < 1 * m) {
|
|
|
|
quality = 60;
|
|
|
|
debugPrint("图片大于 0.5 兆小于 1 兆,质量设置为 60");
|
|
|
|
} else if (length >= 1 * m && length < 2 * m) {
|
|
|
|
quality = 50;
|
|
|
|
} else if (result.length > 2 * 1024 * 1024) {
|
|
|
|
debugPrint("图片大于 1 兆小于 2 兆,质量设置为 50");
|
|
|
|
} else if (length >= 2 * m && length < 3 * m) {
|
|
|
|
quality = 60;
|
|
|
|
} else if (result.length > 1 * 1024 * 1024) {
|
|
|
|
quality = 70;
|
|
|
|
} else if (result.length > 0.5 * 1024 * 1024) {
|
|
|
|
quality = 80;
|
|
|
|
} else if (result.length > 0.25 * 1024 * 1024) {
|
|
|
|
quality = 90;
|
|
|
|
debugPrint("图片大于 2 兆小于 3 兆,质量设置为 40");
|
|
|
|
} else if (length >= 3 * m && length < 4 * m) {
|
|
|
|
quality = 30;
|
|
|
|
debugPrint("图片大于 3 兆小于 4 兆,质量设置为 30");
|
|
|
|
} else {
|
|
|
|
quality = 20;
|
|
|
|
debugPrint("图片大于 4 兆,质量设置为 20");
|
|
|
|
}
|
|
|
|
return quality;
|
|
|
|
}
|
|
|
|
|
|
|
|
//裁剪图片,改变图片大小
|
|
|
|
static Future<Uint8List> resizeImage(Uint8List data) async {
|
|
|
|
/**
|
|
|
|
|
|
|
|
//image插件改变图片尺寸 copyCrop、copyResize 两个方法
|
|
|
|
Uint8List resizedData = data;
|
|
|
|
IMG.Image decodedImage = IMG.decodeImage(data);
|
|
|
|
print(decodedImage.width);
|
|
|
|
print(decodedImage.height);
|
|
|
|
var cropSize = min(decodedImage.width, decodedImage.height);
|
|
|
|
int offsetX =
|
|
|
|
(decodedImage.width - min(decodedImage.width, decodedImage.height)) ~/
|
|
|
|
2;
|
|
|
|
int offsetY =
|
|
|
|
(decodedImage.height - min(decodedImage.width, decodedImage.height)) ~/
|
|
|
|
2;
|
|
|
|
IMG.Image resized = IMG.copyCrop(decodedImage,
|
|
|
|
x: offsetX, y: offsetY, width: 572, height: 457);
|
|
|
|
// IMG.Image resized = IMG.copyResize(decodedImage,
|
|
|
|
// width: 572, interpolation: IMG.Interpolation.cubic);
|
|
|
|
resizedData = IMG.encodeJpg(resized);
|
|
|
|
print(size(resizedData.length));
|
|
|
|
ui.Image im = await fun1(resizedData);
|
|
|
|
print(im.width);
|
|
|
|
print(im.height);
|
|
|
|
return resizedData;
|
|
|
|
*/
|
|
|
|
//image_cropper插件,中心点裁剪固定比例的图片
|
|
|
|
String imgPath = await saveImage(data);
|
|
|
|
Uint8List afterImg = data;
|
|
|
|
if (imgPath != null) {
|
|
|
|
final croppedImage = await ImageCropper().cropImage(
|
|
|
|
sourcePath: imgPath,
|
|
|
|
cropStyle: CropStyle.rectangle,
|
|
|
|
compressQuality: 100,
|
|
|
|
compressFormat: ImageCompressFormat.jpg,
|
|
|
|
aspectRatioPresets: [CropAspectRatioPreset.ratio5x4],
|
|
|
|
// aspectRatio: const CropAspectRatio(ratioX: 0.8, ratioY: 1.0)
|
|
|
|
);
|
|
|
|
print(croppedImage);
|
|
|
|
File yourFile = File(croppedImage.path);
|
|
|
|
|
|
|
|
afterImg = await yourFile.readAsBytes();
|
|
|
|
}
|
|
|
|
|
|
|
|
var resizeBytes = await FlutterImageCompress.compressWithList(
|
|
|
|
result,
|
|
|
|
minHeight: 500,
|
|
|
|
minWidth: 400,
|
|
|
|
quality: quality,
|
|
|
|
// rotate: 135,
|
|
|
|
);
|
|
|
|
IMG.Image decodedImage = IMG.decodeImage(data);
|
|
|
|
print(decodedImage.width);
|
|
|
|
print(decodedImage.height);
|
|
|
|
|
|
|
|
IMG.Image decodedImageafterImg = IMG.decodeImage(afterImg);
|
|
|
|
print(decodedImageafterImg.width);
|
|
|
|
print(decodedImageafterImg.height);
|
|
|
|
debugPrint("newnenwnewnnwen图片的大小:${size(afterImg.length)}");
|
|
|
|
return afterImg;
|
|
|
|
}
|
|
|
|
|
|
|
|
//将回调拿到的Uint8List格式的图片转换为File格式
|
|
|
|
static Future<String> saveImage(Uint8List imageByte) async {
|
|
|
|
bool isGranted = await checkPermissionStorage();
|
|
|
|
if (isGranted) {
|
|
|
|
//获取临时目录
|
|
|
|
var tempDir = await getTemporaryDirectory();
|
|
|
|
//生成file文件格式
|
|
|
|
var file =
|
|
|
|
await File('${tempDir.path}/image_${DateTime.now().millisecond}.jpg')
|
|
|
|
.create();
|
|
|
|
//转成file文件
|
|
|
|
file.writeAsBytesSync(imageByte);
|
|
|
|
print("${file.path}");
|
|
|
|
return file.path;
|
|
|
|
// setState(() {
|
|
|
|
// path = file.path;
|
|
|
|
// // turn(file);
|
|
|
|
// _imageUint8=imageByte;
|
|
|
|
// });
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
print("压缩前:${result.length / 1024}");
|
|
|
|
print("压缩后:${resizeBytes.length / 1024}");
|
|
|
|
/// 根据传入的字节长度,转换成相应的 M 和 KB
|
|
|
|
static String size(int length) {
|
|
|
|
String res = "";
|
|
|
|
final int unit = 1024;
|
|
|
|
final int m = unit * unit; // 1M
|
|
|
|
// 如果小于 1 兆,显示 KB
|
|
|
|
if (length < 1 * m) {
|
|
|
|
res = (length / unit).toStringAsFixed(0) + " KB";
|
|
|
|
}
|
|
|
|
// 如果大于 1 兆,显示 MB,并保留一位小数
|
|
|
|
if (length >= 1 * m) {
|
|
|
|
res = (length / m).toStringAsFixed(1) + " MB";
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Uint8List 转 Image 方式一
|
|
|
|
|
|
|
|
return resizeBytes;
|
|
|
|
/// Uint8List 转 Image 方式二
|
|
|
|
static Future<ui.Image> fun1(Uint8List list) async {
|
|
|
|
ui.Codec codec = await ui.instantiateImageCodec(list);
|
|
|
|
ui.FrameInfo frame = await codec.getNextFrame();
|
|
|
|
return frame.image;
|
|
|
|
}
|
|
|
|
|
|
|
|
//分享邀请函
|
|
...
|
...
|
@@ -1328,7 +1462,8 @@ class Utils { |
|
|
|
String _path =
|
|
|
|
"pages/customer/index?id=$rid&hasInvitation=1&hasSellerShare=1&uid=$uid";
|
|
|
|
String _description = "进入查看包间详情,转发同行好友,还可一键导航到饭店";
|
|
|
|
Uint8List source = await testComporessList(_thumbnail);
|
|
|
|
Uint8List source = await testComporessList(context, _thumbnail);
|
|
|
|
|
|
|
|
//跳转小程序
|
|
|
|
var model = new WeChatShareMiniProgramModel(
|
|
|
|
webPageUrl: _webPageUrl,
|
...
|
...
|
|