Flutter image processing causing pixelation - flutter

Working on a flutter project which needs to take photos and resize / crop images to 640 / 420 (15:10) before uploading to the server but they seem to be too lose too much quality and pixelated.
img.Image image = img.decodeImage(a2);
double width = (image.height / 10) * 15;
image = img.copyCrop(image, ((image.width - width) / 2).round(), 0, width.round(), image.height);
resized = img.encodeJpg(img.copyResize(image, width:640, interpolation: img.Interpolation.cubic));
currently using the camera to shoot at 720p (1280x720) and the image plugin for the crop and resize using average interpolation.
I'm mostly wondering if this is the best way to handle the image processing to keep the most quality or if there is a better method for this use case.

you should try this method, I've been using the following method for myself and it works like charm, the image isn't losing any quality either and the size is way too compressed
final _tempDir = await getTemporaryDirectory();
final _path = _tempDir.path;
im.Image imageFile = im.decodeImage(_file.readAsBytesSync());
mealID = Uuid().v4();
final compressedImageFile = File('$_path/img_$mealID.jpg')
..writeAsBytesSync(im.encodeJpg(imageFile, quality: 80));
setState(() {
_file = compressedImageFile;
});
the above method is for compressing image, and for capturing image from gallery/camera I'm using the method below.
Future getImageFromCamera() async {
Navigator.pop(context);
var image = await ImagePicker.pickImage(
source: ImageSource.camera,
imageQuality: 50,
/*you can set max height and/or width here as well just by setting value for maxHeight and/or maxWidth argument*/
);
setState(() {
_file = image;
});
await compressImage();
}
Future getImageFromGallery() async {
Navigator.pop(context);
var image = await ImagePicker.pickImage(
source: ImageSource.gallery,
imageQuality: 50,
);
setState(() {
_file = image;
});
await compressImage();
}

Related

how to edit the taken picture with flutter

I use Image_picker and provider and some other things to access to camera and gallery and get the photo and save it with Sqlite . there is no problem here but I want to ask is there any solution for editing photo while we take the photo using camera? for example highlight a part of the photo
Future<void> _takePicture() async {
final picker = ImagePicker();
final imageFile =
await picker.pickImage(source: ImageSource.camera, maxHeight: 600);
if (imageFile == null) {
return;
}
setState(() {
_imageFile = File(imageFile.path);
});
this is my method
should I use Image_painter or Image_editor_plus?
you can use Image package in flutter, you can change the brightness using this method from image package
Image image = decodeImage(file.readAsBytesSync());
Image brightenedImage = adjustColor(image, brightness: 0.2);
you can read details of this package here.

Resize image very slow when it process

I want to resize an image and when run my code but resize process is very slow.
My code as below :
void _selectImage() async {
try {
final checkDataImage =
await _imagePicker.pickImage(source: ImageSource.camera);
if (checkDataImage != null) {
print(checkDataImage.name);
print(checkDataImage.path);
setState(() {
pickedImage = checkDataImage;
});
}
} catch (err) {
print(err);
pickedImage = null;
}
final tempDir = await getTemporaryDirectory();
final path = tempDir.path;
Img.Image image = Img.decodeImage(await pickedImage.readAsBytes());
Img.Image smallerImg = Img.copyResize(image, width: 500);
int rand = new Math.Random().nextInt(999999999);
var compressImg = new File('$path/image_$rand.jpg')
..writeAsBytesSync(Img.encodeJpg(smallerImg, quality: 90));
setState(() {
if (!mounted) return;
_imageUpload = compressImg;
});}
What wrong my code, please help to faster it process ?
Thank you for your help.
As others have said, package:image is written in pure Dart and will never be as fast as native solutions that can be multithreaded and hardware accelerated.
While using another isolate will stop the image tasks blocking the UI, if you need to do this as fast as possible, I suggest you use something like the ImageMagick library, or if you only need Android and iOS support, package:flutter_image_compress.

Display Default Image if wasn't picked by Image Picker in Flutter

I have an image picker function, that picks image from gallery and then assigns that to _image variable which is String. It converts it to base64 because that is what was necessary. I want to know how would I go about getting the default image from assets as the _image if no image was picked (picked image is null). Here's the code and things I've tried commented out, it is under else in code:
Future _getImage() async {
PickedFile pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
if (pickedFile != null) {
final file = File(pickedFile.path);
_image = Utility.base64String(file.readAsBytesSync());
} else {
//if image wasn't picked, get the default one from assets
print('No image selected.');
// final file = File(AssetImage('assets/defaultfood.jpg').toString());
// _image = Utility.base64String(file.readAsBytesSync());
//final file = File('assets/defaultfood.jpg');
//_image = Utility.base64String(file.readAsBytesSync());
}
});
}
add image placeholder like this ternary condition
child: pickedFile == null ? Image.asset("assets/images/man_user.png",height: 100, width: 100): Image.file(pickedFile, height: 100, width: 100),

How to resize image using multi_image_picker in Flutter?

I'm using multi_image_picker package to pick images and upload to server, but before uploading I want to resize images. I'm trying to accomplish it using dart.ui but having a problem:
//assets is List<Asset> from MultiImagePicker.pickImages
assets.forEach((asset) {
Future<ByteData> byteData = asset.getByteData();
byteData.then((d) async {
List<int> imageData = d.buffer.asUint8List();
String b64 =base64Encode(imageData);
print(b64); // prints [/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE...
//if i send b64 to server then decode it and save as img it's working well
//Resize
ui.instantiateImageCodec(imageData,targetHeight: 800, targetWidth: 600)
.then((codec) {
codec.getNextFrame().then((frameInfo) async {
ui.Image i = frameInfo.image;
ByteData bytes = await i.toByteData();
List<int> resizedImageData = bytes.buffer.asUint8List();
String rb64 = base64Encode(resizedImageData);
print(rb64); // prints too many backslashes:[k5KO/5qWk/+ZlZL/mpaT/5uXlP+alpP/mJSR/5iUkf+YlJH/mZSR/5uWk/+blpP/n5qX/6GcmP+gm5f/oZyY/6GcmP+fmpb/nZi..
//If i send rb64 to server then server cannot decode and save it.
});
});
});
});
This is the function I normally use to resize:
import 'dart:ui' as skia;
Future<skia.Image> resizeImage(String path, {int width, int height}) async {
Uint8List data = await File(path).readAsBytes();
final codec = await skia.instantiateImageCodec(data, targetWidth: width, targetHeight: height);
final frame = await codec.getNextFrame();
return frame.image;
}
As I mentioned in the comment, this is currently not working in Flutter Web but it's due to a bug that will be fixed soon, hopefully.

image_picker plugin for flutter shows unusual warning

I am using the following code to pick an image with maxHeight/width to save space.
void openGallery()async {
var gallery = await ImagePicker.pickImage(
source: ImageSource.gallery,
maxHeight: maxImageSize,
maxWidth: maxImageSize,
);
if (gallery!=null) {
var bytes = await gallery.readAsBytes();
if (DEBUG) print('Image bytes: ${bytes.length / 1024} KB');
if (DEBUG) print('Image path: ${gallery.path}');
setState(() {
List<int> imageBytes = gallery.readAsBytesSync();
_imageB64 = base64Encode(imageBytes);
// decoded = base64Decode(_imageB64);
if (DEBUG) print('Base64 String length: ${_imageB64.length / 1024} KB');
});
}
}
I am getting this following warning in my console:
image_picker: compressing is not supported for type (null). Returning the image with original quality
flutter: Image bytes: 153.583984375 KB
flutter: Image path: ...myimagpath.jpg
flutter: Base64 String length: 204.78125 KB
1) On one side I can see that my image is reduced in size as it is only 200kB but on the other hand the first line is confusing me.
2) Also, I was under the impression that BASE64 encoded images get smaller in size, As I want to save them to Firebase, will there be a problem saving them as just 'bytes' (as it is 153kb)?
Try this, It's working fine with my code.
var selectedProfileImage;
Future _getImage(bool fromCamera) async {
File image;
if (fromCamera) {
image = await ImagePicker.pickImage(source: ImageSource.camera, maxWidth: 150.0, maxHeight: 150.0);
} else {
image = await ImagePicker.pickImage(source: ImageSource.gallery, maxWidth: 150.0, maxHeight: 150.0);
}
if (image != null) {
// Initiate the ProgessBar
selectedProfileImage = image;
}
}