Getting FirebaseVisionImage from manipulated image in Flutter - flutter

I'm trying to do some pre-processing in my image before using Firebase MLkit. Previously, I was simply loading my image and then passing it directly like this.
File file = await FilePicker.getFile(type: FileType.IMAGE);
final FirebaseVisionImage visionImage = FirebaseVisionImage.fromFile(file);
VisionText visionText = await textRecognizer.processImage(visionImage);
But now, I wanted to do some processing on the image. I did this using Flutter's Image package like this.
import 'package:image/image.dart' as Img;
File file = await FilePicker.getFile(type: FileType.IMAGE);
Img.Image image = Img.decodeImage(file.readAsBytesSync());
var img = Img.invert(image);
Now, how do I pass this new object to FirebaseVisionImage. I see that there is this function:
FirebaseVisionImage.fromBytes(bytes, metadata)
I'm guessing I can get bytes from the above image object using img.getBytes() but I'm confused how to set the metadata.
EDIT:
I see that one can write the image to a temporary file doing
img.writeAsBytesSync(decoded.ToList());
and then use that image again using FirebaseVisionImage.fromFile() but I would really prefer not to do that.

Related

Flutter - How to convert Image to List<Int>?

I want to make the following code work and I do not understand image conversion properly. Would really like someone to point me the right direction to learn this please along with providing a solution to my following problem.
I display the image as a container background image using:
MemoryImage(base64Decode(image)) // My image is in base64 String format here
The above works fine.
Now I have an image path: example-
'/data/user/0/....../cache/scaled_image_picker2751194612758734223.jpg'
How do I go from getting image from this path to base64Encode(image)?
I tried the following up to now and have run out of ideas here:
final Image? image = await Image.file(File(_imagePath));
if (image != null){
setState(() => imageDisplayInContainer = base64Encode(image)); <----Doesn't work
}
Get the file object:
File imageFile = File(_imagePath);
Get the bytes:
List<int> imageBytes = imageFile.readAsBytesSync();
Give the bytes the MemoryImage
MemoryImage(imageBytes);

How can one convert an XFile image from any format to a JPG image for upload?

Right now I'm able to chose an image as XFile using MultiImage picker as follows:
final List<XFile>? images = await _picker.pickMultiImage(maxWidth: _maxWidth, maxHeight:_maxHeight);
which then gives me a list of images which I am able to send into my upload service for uploading to my server
for (var image in images)
{
await myUploadService(image); //image is an XFile
}
Now what I need to do is convert the images, no matter what format they are in, into a JPG image before the upload
So I have tried to convert the images, using the image Flutter package (https://github.com/brendan-duncan/image) as follows:
import 'package:image/image.dart' as ImageConvert;
for (var image in images)
{
//Convert all images to JPG
final newImage = ImageConvert.decodeImage(File(image.path).readAsBytesSync())!;
var newImg = ImageConvert.encodeJpg(newImage);
var newImg2 = Image.memory(Uint8List.fromList(newImg)) as XFile; // <--- the main problem
await myUploadService(newImg2);
}
But this isn't working, mainly at the point where I try to put the image back into an XFile format for upload with my upload service
So the main question is here is how can I convert the newly encoded JPG image back to XFile format?
Open to totally different strategies of dealing with this issue as well

flutter image picker reduce file size with provider and flutter_image_compress

I am using image picker to pick image from device(App) and after that stored that file in provider class like that.
File? _img;
get img=> _img;
void putbannerimg(File img) {
_img = img;
notifyListeners();
}
I found out that image picker does not compress png images, I tried compressing it with flutter_image_compress
compressFile() async {
final formservice = Provider.of<PostForm>(context, listen: false);
File file = formservice.bannerfile;
final result = await FlutterImageCompress.compressWithFile(
file.absolute.path,
quality: 54,
);
formservice.putbannerimg(File.fromRawPath(result!));
}
I tried this way And other multiple ways but getting different different errors I want to upload this file in firebase storage like this
var task = storageicon.putFile(formservice.iconfile);
please tell me where I am going wrong, without compress file all things are working fine
Edit: I found out that path should be a string how can I parse local code file in that
If you are using the "flutter_image_compress" package
You may have to use the compress function for files stored on the phone like this:
Future<File> testCompressAndGetFile(File file, String targetPath) async {
var result = await FlutterImageCompress.compressAndGetFile(
file.absolute.path, targetPath,
quality: 88,
rotate: 180,
);
print(file.lengthSync());
print(result.lengthSync());
return result;
}
"compressAndGetFile()" returns a file while "compressWithFile()" returns a Uint8List.
If i understand your last question right, you want to use an image built into your application by default.
For this, you have to open your "pubsepc.yaml", go to the "flutter:" mark and add "assets:" like so:
flutter:
assets:
- path
"path", in my example, describes a top level folder containing assets like pictures.
You can freely describe its name.

Store image uploaded by user into Flutter Web as an actual .jpg file

I am using the flutter_web_image_picker package to allow the user to select -and then upload to Firebase- an image.
However, the package returns an image widget, which I can display, but I cannot upload to Firebase. Therefore, I am trying to read the package's code and update it to fit my needs.
In general, I think the packages main functionalities are:
It gets the file
//...
final reader = html.FileReader();
reader.readAsDataUrl(input.files[0]);
await reader.onLoad.first;
final encoded = reader.result as String;
Then it 'strippes' it
final stripped = encoded.replaceFirst(RegExp(r'data:image/[^;]+;base64,'), '');
final imageName = input.files?.first?.name;
//...
To finally return it as a Widget:
final imageName = imageName;
final imageData = base64.decode(stripped);
return Image.memory(imageData, semanticLabel: imageName);
As I said, it works perfectly, however, I need to adapt it to my needs:
I would like to get the image as a .jpg file so that I can upload it to Firebase.
Is any of the variables above the actual .jpg file? Is there any transformation that I should perform to get a .jpg file?
Thanks!
I based my answer on this post.
Basically, on the flutter_web_image_picker package, before the code I posted, there were a few lines that get an actual html file:
final html.FileUploadInputElement input = html.FileUploadInputElement();
input..accept = 'image/*';
input.click();
await input.onChange.first;
if (input.files.isEmpty) return null;
Then using firebase's pacakge, I uploaded the image as follow:
import 'package:firebase/firebase.dart' as fb;
fb.StorageReference storageRef = fb.storage().ref('myLocation/filename.jpg');
fb.UploadTaskSnapshot uploadTaskSnapshot = await storageRef.put(input.files[0]).future;
Uri imageUri = await uploadTaskSnapshot.ref.getDownloadURL();
return imageUri;

How to Share Image from API(URL) in flutter?

Here I want to share image which I get through API. I tried different method for this functionality but I did not get any solution because every solutions have for only one image.
Exactly, I get multiple image from Url and I open any particular image in next page. So, I want to share that image which I opened in another page.
I tried for sharing image but I could not did this. Whenever I try to share that image, Image url share with sharing option on device but I want share image not URl of image How I can accomplish this?
You have to download the image like this:
http.Response response = await http.get(url);
then create an image on the device using the downloaded image like this (Read and Write Files):
final directory = await getTemporaryDirectory();
final path = directory.path;
final file = File('$path/image.png');
file.writeAsBytes(response.bodyBytes);
The getTemporaryDirectory() is in the plugin path_provider. Now, you have the image you'd like to share stored in the temporarily as "image.png" and you can use the share_plus plugin to share the image like this:
Share.shareFiles(['$path/image.png']);
Thanks to #abdulrazak, At first, you have to download the image in a temporary path & then you can share the image as you want. used Dio to download the image & share_plus for sharing
void _shareNetworkImage(String url) async {
Directory tempDir = await getTemporaryDirectory();
final path = '${tempDir.path}/test.jpeg';
await Dio().download(url, path);
Share.shareFiles([path]);
}
You can use the esys_flutter_share plugin.
Install it, and then get dependencies:
dependencies:
esys_flutter_share: ^1.0.2
Import the plugin to your code:
import 'package:esys_flutter_share/esys_flutter_share.dart';
Use the below code:
var request = await HttpClient().getUrl(Uri.parse('https://yourImageURL.jpg'));
var response = await request.close();
Uint8List bytes = await consolidateHttpClientResponseBytes(response);
await Share.file('ESYS AMLOG', 'amlog.jpg', bytes, 'image/jpg');