Flutter image cropper not showing image to be cropped - flutter

I managed to choose an image from gallery using the image picker and it is as follows
Future pickImage() async {
File _originalImage = await ImagePicker.pickImage(
source: ImageSource.camera);
if (_originalImage != null) {
File _croppedImage = await ImageCropper.cropImage(
sourcePath: _originalImage.path,
aspectRatioPresets: [
CropAspectRatioPreset.square,
CropAspectRatioPreset.ratio3x2,
CropAspectRatioPreset.original,
CropAspectRatioPreset.ratio4x3,
CropAspectRatioPreset.ratio16x9
],
androidUiSettings: AndroidUiSettings(
toolbarColor: BaengColors.blue,
toolbarTitle: 'Baeng Omang Cropper',
statusBarColor: BaengColors.blue[700],
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false
)
);
this.setState(() {
_imagePicked = _croppedImage;
isLoaded = true;
getTextFromImage();
});
}
}
Tried to debug it several times and it was not showing any kind of bug nor problem, but the image cropping activity remains black(without) the image selected from the image picker.
Please help

Just add maxHeight And maxWidth in Image_Picker
File _originalImage = await ImagePicker.pickImage(source: ImageSource.camera,
imageQuality: 20,
maxHeight: 500,maxWidth: 500);

Related

Flutter Upload Images

I try to use upload image from Flutter libary, but it doesn't work. The codes just run to gallery and choose the image, but the image doesn't show to the screen.
Please help me to make it work, from choosing the image and show the image result that I choose. Thanks
You have to update the state of the screen for seeing the changes. If you are using stateful just simply use setState to do this.
setState(() {
uploadFile = File(image!.path);
});
I hope this answer will help you.
static String? pickImage({bool useCamera = false, bool crop = true,
CropAspectRatio ratio = const CropAspectRatio(
ratioX: 1, ratioY: 1,
)}) {
ImagePicker().pickImage(source: useCamera ? ImageSource.camera : ImageSource.gallery, imageQuality: 60).then((pickedFile) {
if (pickedFile == null || !File(pickedFile.path).existsSync()) {
return Stream.error(Exception('No image picked!'));
}
if (crop) {
ImageCropper().cropImage(sourcePath: pickedFile.path ?? '', aspectRatio: ratio, uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Cropper',
toolbarColor: AppStyles.primary500Color,
toolbarWidgetColor: Colors.white,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false),
IOSUiSettings(
title: 'Cropper',
),
]).then((value) {
if (value != null) {
croppedFile = value;
// selectedPhotoStream.add(croppedFile);
/// ** You are missing **
setState((){
uploadFile = croppedFile.path;
});
return croppedFile?.path;
}
});
}
});
return croppedFile?.path;
}

Flutter image_cropper plugin error: "You need to use a Theme.AppCompat > theme (or descendant) with this activity"

I'm using Flutter's image_cropper plugin & it's throwing an error about AppCompat:
java.lang.RuntimeException: Unable to start activity
ComponentInfo{uk.co.pottertour.meloan/com.yalantis.ucrop.UCropActivity}:
java.lang.IllegalStateException: You need to use a Theme.AppCompat
theme (or descendant) with this activity.
What happens is:
I launch the camera from my profile edit screen, after the user takes a photo, it should then launch the crop activity, but it throws that error and crashes my entire app.
This has started to happen with the latest image_cropper plugin upgrade, 2.0.3.
Future getImage(ImageSource _imageSource) async {
final pickedFile =
await imagePicker.pickImage(source: _imageSource, imageQuality: 85);
if(pickedFile == null) return;
print(LOG + "getImage file from camera path: ${pickedFile.path}");
_cropImage(pickedFile.path);
setState(() {
_image = File(pickedFile.path);
});
imageChanged = true;
}
Future<Null> _cropImage(String imageFilePath) async {
final croppedFile = await ImageCropper().cropImage(
compressQuality: 80,
sourcePath: imageFilePath,
maxWidth: 428,
maxHeight: 428,
aspectRatioPresets: Platform.isAndroid
? [
CropAspectRatioPreset.square,
]
: [
CropAspectRatioPreset.square,
],
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Cropper',
toolbarColor: Colors.deepOrange,
toolbarWidgetColor: Colors.white,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: true),
IOSUiSettings(
title: 'Cropper',
)
]);
if (croppedFile != null) {
setState(() {
_image = File(croppedFile.path);
});
}
}
I tweaked the cropper code, to the revised format suggested in the plugin's readme but to no avail. I wonder if the screen needs to rebuild after the camera completes but because the camera & _cropImage methods are async, it doesn't in time, so Flutter doesn't have appCompat inherited from the root widget from main.dart.
To use the plugin add this to AndroidManifest.xml. Pay attention especially to the last line.
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="#style/Theme.AppCompat.Light.NoActionBar"/>

Error: Member not found: 'ImageCropper.cropImage' [duplicate]

This question already has answers here:
error: Instance member 'cropImage' can't be accessed using static access
(2 answers)
Closed 12 months ago.
**i spent all night trying get cropped image, need some help **
image_cropper: ^1.5.0 # Used to Crop/Rotate Selected images from user's device
///Error
Error: Member not found: 'ImageCropper.cropImage'.
final croppedImage = await ImageCropper.cropImage(
///images_source
class ImageSourceSheet extends StatelessWidget {
// Constructor
ImageSourceSheet({required this.onImageSelected});
// Callback function to return image file
final Function(File?) onImageSelected;
// ImagePicker instance
final picker = ImagePicker();
Future<void> selectedImage(BuildContext context, File? image) async {
// init i18n
final i18n = AppLocalizations.of(context);
// Check file
if (image != null) {
final croppedImage = await ImageCropper.cropImage(
sourcePath: image.path,
aspectRatioPresets: [CropAspectRatioPreset.square],
maxWidth: 400,
maxHeight: 400,
androidUiSettings: AndroidUiSettings(
toolbarTitle: i18n.translate("edit_crop_image"),
toolbarColor: Theme.of(context).primaryColor,
toolbarWidgetColor: Colors.white,
));
onImageSelected(croppedImage);
}
}
You need to use ImageCropper().cropImage(...).
final croppedImage = await ImageCropper().cropImage(....)
You can check example code.

error: Instance member 'cropImage' can't be accessed using static access

class ImagesCropper {
static Future<File?> cropImage(XFile file) async {
final File? croppedImage = await ImageCropper.cropImage(
sourcePath: file.path,
aspectRatioPresets:
Platform.isAndroid ? crossAspectRatioAndroid : crossAspectRatioIos,
androidUiSettings: androidUiSettings,
iosUiSettings: iosUiSettings,
);
return croppedImage;
}
}
i put the full code here:
https://controlc.com/9590e7b1
and here's the error in debug console
debug console
Just change ImageCropper.cropImage to ImageCropper().cropImage. This will use a new instance of ImageCropper.
It looks like you are using the ImageCropper package. https://github.com/hnvn/flutter_image_cropper/blob/master/lib/src/cropper.dart#L61 There was an error because the method isn't static so you have to create a new instance of the class to access it
await ImageCropper().cropImage...
The full code correction is below
class ImagesCropper {
static Future<File?> cropImage(XFile file) async {
final File? croppedImage = await ImageCropper().cropImage(
sourcePath: file.path,
aspectRatioPresets:
Platform.isAndroid ? crossAspectRatioAndroid : crossAspectRatioIos,
androidUiSettings: androidUiSettings,
iosUiSettings: iosUiSettings,
);
return croppedImage;
}
}

Issues with Image selection from disk Flutter

I have this form where I need to upload a profilePic and companyLogo. Earlier I faced some issues regarding updating images on the selection which I fixed using : imageCache.clear() & imageCache.clearLiveImages() and passing Unique key to Image.file widgets.
Now, the problem is, if I select the profile Pic then select the company Logo & When I send the images as Multipart in FormData, it uses the file which I selected later for both, i.e, if I select _companyLogo after _profilePic, it replaces _profilePic data with _companyLogo, however the displaying images remains correct for Image.file widget.
//Widgets using GestureDetector to call onAddProfilePic() and onAddCompanyLogo()
File _profilePic;
Key _keyProfilePic = Key('key1');
Image.file(
_profilePic,
fit: BoxFit.cover,
key: _keyProfilePic,
)
File _companyLogo;
Key _keyCompanyLogo = Key('key2');
Image.file(
_companyLogo,
fit: BoxFit.cover,
key: _keyCompanyLogo,
)
onAddProfilePic(){
Utils.selectImage(context, (newPic) {
if(newPic != null){
_profilePic = newPic;
_keyProfilePic = Key(Uuid().v4());
setState(() {});
}
});
}
onAddCompanyLogo(){
Utils.selectImage(context, (newPic) {
if(newPic != null){
_companyLogo = newPic;
_keyCompanyLogo = Key(Uuid().v4());
setState(() {});
}
});
}
The function selectImage is in Utils Class
static Future<void> selectImage(context, callback, {int minSize = 480, double ratioX = 1.0, double ratioY = 1.0}) async {
int sourceSelected = await showDialog(context: context, builder: (context) => DialogImagePicker());
if(sourceSelected == null) return;
var pickedImage = await ImagePicker().getImage(source: sourceSelected == 0 ? ImageSource.camera : ImageSource.gallery);
if(pickedImage==null) return;
File croppedFile = await ImageCropper.cropImage(
maxWidth: (minSize * ratioX).toInt(),
maxHeight: (minSize * ratioY).toInt(),
compressFormat: ImageCompressFormat.jpg,
sourcePath: pickedImage.path,
aspectRatio: CropAspectRatio(ratioX: ratioX, ratioY: ratioY),
compressQuality: 80,
androidUiSettings: AndroidUiSettings(
toolbarColor: kDarkBlueColor,
toolbarTitle: 'Crop Image',
hideBottomControls: true,
toolbarWidgetColor: Colors.white
),
);
if(croppedFile == null){
return;
}
croppedFile = croppedFile.renameSync(path.join(path.dirname(croppedFile.path), 'image'+'.jpg'));
print('Cropped file :$croppedFile');
imageCache.clear();
imageCache.clearLiveImages();
callback(croppedFile);
}
The problem is, since I was cropping the image & was changing the cropped file name, which was replacing previous images with newly selected ones. Not renaming so fixed the issue.
Additional to this, no unique key or image cache clearance is required.
Updated code:
File _profilePic;
Image.file(
_profilePic,
fit: BoxFit.cover,
)
File _companyLogo;
Image.file(
_companyLogo,
fit: BoxFit.cover,
)
onAddProfilePic(){
Utils.selectImage(context, (newPic) {
if(newPic != null){
_profilePic = newPic;
setState(() {});
}
});
}
onAddCompanyLogo(){
Utils.selectImage(context, (newPic) {
if(newPic != null){
_companyLogo = newPic;
setState(() {});
}
});
}
static Future<void> selectImage(context, callback, {int minSize = 480, double ratioX = 1.0, double ratioY = 1.0}) async {
int sourceSelected = await showDialog(context: context, builder: (context) => DialogImagePicker());
if(sourceSelected == null) return;
var pickedImage = await ImagePicker().getImage(source: sourceSelected == 0 ? ImageSource.camera : ImageSource.gallery);
if(pickedImage==null) return;
File croppedFile = await ImageCropper.cropImage(
maxWidth: (minSize * ratioX).toInt(),
maxHeight: (minSize * ratioY).toInt(),
compressFormat: ImageCompressFormat.jpg,
sourcePath: pickedImage.path,
aspectRatio: CropAspectRatio(ratioX: ratioX, ratioY: ratioY),
compressQuality: 80,
androidUiSettings: AndroidUiSettings(
toolbarColor: kDarkBlueColor,
toolbarTitle: 'Crop Image',
hideBottomControls: true,
toolbarWidgetColor: Colors.white
),
);
if(croppedFile == null){
return;
}
//croppedFile = croppedFile.renameSync(path.join(path.dirname(croppedFile.path), 'image'+'.jpg'));
callback(croppedFile);
}