Commit 0d0625fb53b62d59cd845d93e5354368fcf09834

Authored by wdn127929
1 parent 1a963547

分享小程序封面图裁切成固定比例5:4

... ... @@ -12,14 +12,14 @@ if (flutterRoot == null) {
}
def flutterVersionCode = "443"
def flutterVersionCode = "444"
if (flutterVersionCode == null) {
flutterVersionCode = '443'
flutterVersionCode = '444'
}
def flutterVersionName = "4.4.3"
def flutterVersionName = "4.4.4"
if (flutterVersionName == null) {
flutterVersionName = '4.4.3'
flutterVersionName = '4.4.4'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
... ...
... ... @@ -110,5 +110,10 @@
android:name="com.amap.api.v2.apikey"
android:value="13464ddadd6a5d825e79f90e10ba72d2"/>
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
</application>
</manifest>
... ...
... ... @@ -2,4 +2,4 @@ org.gradle.jvmargs=-Xmx1536M
# org.gradle.jvmargs=-Xmx2048M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
\ No newline at end of file
android.enableJetifier=true
... ...
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
Future<bool> checkPermissionStorage() async {
var status = await Permission.storage.status;
if (!status.isGranted) {
status = await Permission.storage.request();
if (status.isGranted) {
return true;
}
} else {
return true;
}
return false;
}
Future<bool> checkContactPermission() async {
PermissionStatus permissionStatus = await Permission.contacts.status;
if (permissionStatus == PermissionStatus.granted) {
... ...
... ... @@ -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,
... ...
... ... @@ -43,6 +43,13 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.1.0"
archive:
dependency: transitive
description:
name: archive
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.3.6"
args:
dependency: transitive
description:
... ... @@ -637,6 +644,34 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.0.1"
image:
dependency: "direct main"
description:
name: image
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.0.15"
image_cropper:
dependency: "direct main"
description:
name: image_cropper
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.1"
image_cropper_for_web:
dependency: transitive
description:
name: image_cropper_for_web
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.3"
image_cropper_platform_interface:
dependency: transitive
description:
name: image_cropper_platform_interface
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.3"
image_gallery_saver:
dependency: "direct main"
description:
... ... @@ -903,6 +938,13 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.1.0"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.1.0"
photo_manager:
dependency: transitive
description:
... ... @@ -931,6 +973,13 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.2"
pointycastle:
dependency: transitive
description:
name: pointycastle
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.6.2"
pool:
dependency: transitive
description:
... ... @@ -1421,6 +1470,13 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.2.0+1"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.1.0"
yaml:
dependency: transitive
description:
... ...
... ... @@ -181,6 +181,8 @@ dependencies:
extended_text_field: ^10.1.1
image_gallery_saver: ^1.7.1
flutter_image_compress: ^1.1.3
image: ^4.0.15
image_cropper: ^3.0.1
#表格多选组建
... ...