How to compress image asset from multi_image_picker flutter? - flutter

Libraries used: https://pub.dev/packages/multi_image_picker, https://pub.dev/packages/flutter_image_compress
I am using multi image picker lib to get multiple images from the gallery. However, before uploading them I want to compress image's size first.
Multiple image picker return List<Asset> but in flutter_image_compress lib, we can only compress image as a type of File like this:
Future<Uint8List> testCompressFile(File file) async {
var result = await FlutterImageCompress.compressWithFile(
file.absolute.path,
minWidth: 2300,
minHeight: 1500,
quality: 94,
rotate: 90,
);
return result;
}
How can I convert List<Asset> to List<File> in order to compress image?

I solved this problem. Please check my full source code here: https://soksereyphon8.medium.com/upload-multiple-images-and-compress-image-in-flutter-62d113a3247a

Related

Flutter, image_crop scale, resolution, size, quality issue

I`m using this package https://pub.dev/packages/image_crop
I want to upload a 4000x4000 quality picture to the server after converting it to 1080.
Firstly, I do the below
final pickedFile = await ImagePicker()
.pickImage(source: ImageSource.gallery, imageQuality: 100);
if (pickedFile == null) {
return;
}
final file = File(pickedFile.path);
final sample = await ImageCrop.sampleImage(
file: file, preferredWidth: 4000, preferredHeight: 4000
);
and then secondly I do the below
final sample = await ImageCrop.sampleImage(
file: file_tmp!,
preferredSize: (4000 / scale).round(),
);
and then lastly I do the below
final full = class_image.copyResize(image,
height: 1080, width: 1080);
I don't know if I'm getting it right now. Every time I change the value of preferredSize, the size of the final image file seems to change, and in the case of image_crop, the first scale is automatically set to 0.5, which causes deterioration in image quality.
First of all, I want to change the scale to 1.0, and I want it to come out without enlarging the screen. (This seems to cause quality degradation)
And please check if my logic is okay
If anyone knows this package well, please reply.

Flutter: Image Package Crop to Circle

I am using the Image package to handle and process images in a flutter app. In this case, I am downloading the users profile pic and attempting to resize it and crop it to a circle. However, it does not appear to be cropping the image at all. Am I missing something here?
import 'package:image/image.dart' as ui;
final getProfile = await http.get(Uri.parse(profilePicPath));
final profileFile = File('${(await getTemporaryDirectory()).path}/image.png');
await profileFile.create(recursive: true);
await profileFile.writeAsBytes(getProfile.bodyBytes);
ui.Image profileImage = ui.decodeImage(profileFile.readAsBytesSync());
ui.copyCropCircle(profileImage, radius: 10);
Edit: I need to keep the image as a file and will not be shown in the UI (eventually used to overlay in another image file).
For anyone who runs into this issue, it was only a slight modification that got it to work. This pulls in the photo, stores it, resizes it, and then crops it to a cricle.
import 'package:image/image.dart' as ui;
final getProfile = await http.get(Uri.parse(profilePicPath));
final profileFile = File('${(await getTemporaryDirectory()).path}/image.png');
await profileFile.create(recursive: true);
await profileFile.writeAsBytes(getProfile.bodyBytes);
ui.Image profileImage = ui.decodeImage(profileFile.readAsBytesSync());
profileImage = ui.copyResize(profileImage, height: 100, width: 100);
profileImage = ui.copyCropCircle(profileImage, radius: 50);

Flutter display package:image/image.dart:Image in UI Widget

We can work on images in Flutter using import 'package:image/image.dart' as ToolsImage; package to scale them with ToolsImage.copyResize() and manipulate individual pixels with ToolsImage.Image.getPixel(x,y)
To display image from memory bytes (ByteData/Uint8List/List<int>) we can use MemoryImage:
Container(child: Image(image: MemoryImage(image.data.buffer.asUint8List())))
I'm getting an exception:
Exception: Invalid image data
whichever List I use. What's wrong?
Remember to add HEADER to image bytes after format conversions!
ByteData imageByteData = await rootBundle.load('res/images/basic/dizzy-face.png');
List<int> values = imageByteData.buffer.asUint8List();
ToolsImage.Image? photo = ToolsImage.decodeImage(values);
photo = ToolsImage.copyResize(photo!, height: 32, width: 32);
removes header information (pixel-by-pixel manipulation removes header info).
Use:
List<int>? imageWithHeader = ToolsImage.encodeNamedImage(TEST_IMAGE, ".bmp");
and then:
Container(child: Image(image: MemoryImage(Uint8List.fromList(imageWithHeader))))
Last line enables us to convert package:image/image.dart to package:flutter/src/widgets/image.dart (UI Image Widget)

How to limit wechat asset picker to only JPG imges

In my app I want to allow users to pick multiple photos, I am usin for this Wechat Asset Picker, as I need to put a limit nfor number of photos can be selected.
afer that I need to compress these photos to reduce their siz befor uploadting to firestore.
I have two problems:
first, we chat asset picker package show all assets on the device, images, videos, etc. while I need to alow user only to upload images.
second, I am using Flutter Image Compress package for compressing, which works only with JPG.
Is there any better packages for my objective?
if not, my questions is how to limit wechat asset picker to only jpg images?
snapshots of code:
final List<myimagepicker.AssetEntity>? result =
await myimagepicker.AssetPicker.pickAssets(
context,
pickerConfig: const myimagepicker.AssetPickerConfig(
gridCount: 3,
maxAssets: 10,
pickerTheme: null,
themeColor: Color.fromARGB(255, 245, 91, 165),
pageSize: 30,
),
var result = await FlutterImageCompress.compressAndGetFile(
imageslist[i].absolute.path,
outPath,
quality: 50,
);
resultList = await AssetPicker.pickAssets(
context,
pickerConfig: const AssetPickerConfig(
maxAssets: 3,
requestType: RequestType.image, ✅
),
only jpg?
don't know
but only image?
you can set requestType.

Unable to load asset in Flutter

I'm sharing a picture that I've taken previously with the camera using image_picker. It works fine on the emulator but not on my device:
onPressed: () async {
ByteData image = await rootBundle.load(team.avatar.path);
...
},
This is the error with the path:
Unable to load asset:
/storage/emulated/0/Android/data/drodriguez.apps.Words/files/Pictures/scaled_2eccad3d-382e-462e-b124-b8fa06a2a32b791445736175256137.jpg
The image is being shown without errors so the path is 100% correct:
Image.file(
_orderedTeams[index].avatar,
fit: BoxFit.cover,
height: 92.0,
width: 92.0,
)
Do I need to add something else maybe on the pubspec.yml?
You can't use the rootBundle to access files on the phone. The rootBundle (as said in its docs) only works for files packaged with the application when was built (probably saved on assets, declared on pubspec, etc).
If you want to load an image from the phone, this maybe help.
ANSWER
This function can read a filePath and return a Uint8List (a byteArray):
Future<Uint8List> _readFileByte(String filePath) async {
Uri myUri = Uri.parse(filePath);
File audioFile = new File.fromUri(myUri);
Uint8List bytes;
await audioFile.readAsBytes().then((value) {
bytes = Uint8List.fromList(value);
print('reading of bytes is completed');
}).catchError((onError) {
print('Exception Error while reading audio from path:' +
onError.toString());
});
return bytes;
}
And, to get a ByteData just:
var path = 'Some path to an image';
var byteArray = _readFileByte(path);
ByteData data = ByteData.view(byteArray.buffer);
(The answer is based on this)