Обрезка изображения не работает в GetxController
Ниже приведен код, который я пытался реализовать. Будущий метод pickImage, я думаю, проблема именно в нем. Я расширяю класс с помощью GetxController. Ожидается, что метод выберет и обрежет выбранное изображение с помощью обрезки изображения, а затем установит обрезанное изображение в переменную imageFile, если обрезка прошла успешно.
import 'dart:io';
import 'package:pamoja/app/data/const.dart';
import 'package:pamoja/app/data/firebase/firebase_functions.dart';
import 'package:pamoja/app/data/global_widgets/indicator.dart';
import 'package:pamoja/app/models/advert_model.dart';
import 'package:pamoja/app/modules/my_adverts/controllers/my_adverts_controller.dart';
import 'package:pamoja/app/routes/app_pages.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image_cropper/image_cropper.dart';
class UploadBlogController extends GetxController {
TextEditingController title = TextEditingController();
TextEditingController description = TextEditingController();
TextEditingController location = TextEditingController();
TextEditingController category = TextEditingController();
TextEditingController price = TextEditingController();
TextEditingController phone = TextEditingController();
final FirebaseFunctions _functions = FirebaseFunctions();
File? imageFile;
Future<void> pickImage() async {
try {
ImagePicker _picker = ImagePicker();
await _picker.pickImage(source: ImageSource.gallery).then((value) async {
if (value != null) {
File? croppedFile = await ImageCropper().cropImage(
sourcePath: value.path,
aspectRatio: CropAspectRatio(ratioX: 1, ratioY: 1),
compressQuality: 100,
maxWidth: 700,
maxHeight: 700,
// saveCircleCroppedImage: true,
);
if (croppedFile != null) {
imageFile = croppedFile;
update();
}
}
});
} catch (e) {
showAlert("$e");
}
}
void createBlog() async {
if (title.text.isNotEmpty && description.text.isNotEmpty) {
if (imageFile != null && imageFile != "") {
Indicator.showLoading();
await _functions
.uploadBlog(
title.text,
description.text,
imageFile!,
price.text,
category.text,
location.text,
phone.text,
)
.then((value) {
Indicator.closeLoading();
showAlert("Your advert created sucessfully");
// Get.back();
Get.toNamed(Routes.HOME);
});
} else {
showAlert("Image is required");
}
} else {
showAlert("All fields are required");
}
}
void editBlog(BlogsModel model) async {
Indicator.showLoading();
if (title.text.isNotEmpty && description.text.isNotEmpty) {
if (imageFile == null) {
Map<String, dynamic> map = {
'title': title.text,
'description': description.text,
};
await _functions.editBlog(model.id, map).then((value) {
Get.toNamed(Routes.HOME);
showAlert("Your ads Updated Sucessfully");
});
} else {
String imageUrl = await _functions.uploadImage(imageFile!);
Map<String, dynamic> map = {
'title': title.text,
'description': description.text,
'img': imageUrl,
};
await _functions.editBlog(model.id, map).then((value) {
Get.toNamed(Routes.HOME);
showAlert("Your Advert Updated Sucessfully");
});
}
} else {
showAlert("All fields are required");
}
Indicator.closeLoading();
updateData();
}
void updateData() {
Get.back();
Get.toNamed(Routes.HOME);
if (Get.isRegistered<MyBlogsController>()) {
final controller = Get.find<MyBlogsController>();
controller.myBlogs = [];
Indicator.showLoading();
controller.getMyBlogData();
}
}
}
2 ответа
это я создалreusable single-tone
код для всего моего приложения, чтобы выбрать медиаimage
илиvideo
. вы можете попробовать или изменить в соответствии с вашими требованиями.
// Dart imports:
import 'dart:io';
// Package imports:
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
// Project imports:
import 'package:app/utils/export_utils.dart';
class MediaPicker {
MediaPicker._();
static const supportedImageFormates = [".jpeg", ".png"];
static const supportedVedioFormates = [".mp4"];
static final picker = ImagePicker();
// Single image / video selection
static Future<File?> pickMedia({
required ImageSource source,
bool isVideo = false,
bool isEditing = false,
}) async {
try {
final pickMedia = !isVideo
? await picker.pickImage(source: source)
: await picker.pickVideo(source: source);
if (pickMedia != null) {
return isEditing
? await editImage(file: File(pickMedia.path))
: File(pickMedia.path);
} else {
return null;
}
} catch (ex) {
"Pick Media error: $ex".printLog();
return null;
}
}
static Future<File> editImage({required File file}) async {
final CroppedFile? croppedFile = await ImageCropper().cropImage(
sourcePath: file.path,
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Cropper',
toolbarColor: ColorConst.themePrimaryColor,
toolbarWidgetColor: ColorConst.white,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false,
),
IOSUiSettings(
title: 'Cropper',
),
],
);
if (croppedFile != null) {
return File(croppedFile.path);
} else {
return file;
}
}
}
Использование метода добавления вызова при нажатии кнопки с помощьюFuture
&async
метод
Future<void> btnPickImageTap() async {
final File? selectImageFile = await MediaPicker.pickMedia(
source: ImageSource.gallery,
isEditing: true, // Default false
);
}
source: ImageSource.camera - to pick image from camera.
isEditing: false - avoid image cropping functionality.
isVideo: to pick video from gallery / camera.
Убедитесь, что для обеих платформ добавлено следующее разрешение
Andriod
- AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA"/> //Camera
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> // Read Storage
iOS
Бегун/info.plist
<key>NSCameraUsageDescription</key>
<string>App require camera permission to update profile pic</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>App require gallery permission to update profile pic</string>
Как указано в пакетеimage_cropper
добавьте приведенный ниже код вAndroidManifest.xml
под<applcaiton>
ЯРЛЫК
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
Я изменил его по вашей инструкции, это сработало. Ниже приведен пример модификации
Future<void> pickImage() async {
try {
ImagePicker _picker = ImagePicker();
await _picker.pickImage(source: ImageSource.gallery).then((value) async {
if (value != null) {
imageFile = File(value.path);
showAlert(imageFile.toString());
editImage(imageFile: imageFile);
// cropImage(imageFile);
} else {
showAlert("No image selected");
}
});
} catch (e) {
showAlert("$e");
}}
Future<void> editImage({required File? imageFile}) async {
final File? croppedFile = await ImageCropper().cropImage(
sourcePath: imageFile!.path,
androidUiSettings: AndroidUiSettings(
toolbarTitle: 'Advert Image',
toolbarColor: Colors.green.shade400,
toolbarWidgetColor: Colors.white,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false,
),
iosUiSettings: IOSUiSettings(
title: 'Cropper',
),
);
if (croppedFile != null) {
imageFile = File(croppedFile.path);
update();
} else {
// update();
}}