how to convert image to byte and again convert it to image in flutter? - image

I am trying to use the image_picker plugin. I can get the image as file using this plugin. I need to convert this image to bytes and send to a api. So I tried to use dart:convert to convert the image to byte string. Now when I decode I am getting a Uint8List type. How to convert this to a file and display in a Image.file(). I couldn’t proceed from here. Can someone help me with this.
consider i am getting this decodedBytes i am getting from a api response, how can i convert them to display in a Image widget
This is the code I tried so far.
var image = await ImagePicker.pickImage(source: ImageSource.camera);
setState(() {
imageURI = image;
final bytes = image.readAsBytesSync();
String img64 = base64Encode(bytes);
print(bytes);
print(img64);
final decodedBytes = base64Decode(img64);
print(decodedBytes);
//consider i am getting this decodedBytes i am getting from a api response, how can i convert them to display in a Image widget
});
I am getting this error using writeAsBytesSync(),
Unhandled Exception: FileSystemException: Cannot open file, path = 'decodedimg.png'

You get this error, because you can't write to any arbitrary location in an application sandbox. You can use path_provider to look up a temporary directory.
But in your case, just use the image object, pickImage already returns a File object, so just use Image.file(image)
If you want to decode a base64 into a temporary directory you can use:
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
Future<File> writeImageTemp(String base64Image, String imageName) async {
final dir = await getTemporaryDirectory();
await dir.create(recursive: true);
final tempFile = File(path.join(dir.path, imageName));
await tempFile.writeAsBytes(base64.decode(base64Image));
return tempFile;
}
with pubspec.yaml:
dependencies:
path: ^1.6.0
path_provider: ^1.6.7

Related

How to Transform a Blob to An Image in flutter

i want to display an image stored in mysql database
the problem is that i can't convert the blob format into a Uint8list ; i searched and found soulitions but none of them works
Grab the blob from JSON:
var blob = yourJSONMapHere['yourJSONKeyHere'];
var image = BASE64.decode(blob); // image is a Uint8List
Now, use image in a Image.memory
new Container( child: new Image.memory(image));
this soulition didn't work because base64.decode need a string source not a blob file to convert
Don't know if it is relatable to this particular case but had similar issue with Cloud Firestore.
Created blob for storing in this way:
Blob myBlob = Blob(await audioFile.readAsBytes());
saved to Firestore in one field as usual
Then tried to read it back and couldn't figure it out how to get Uint8List from blob I get back from Firestore.
my solution:
//extract blob from field of Firestore document
Blob audioBlob = audioDocFromDb.get("fieldName");
//use .bytes on blob from this source
//package:cloud_firestore_platform_interface/src/blob.dart
Uint8List audioBytes = audioBlob.bytes;
this worked for me.
In my case I was packing up recorded audio and trying to play it back.
I had this problem too, i know the solution now, after many attempts:
Dont forget to upvote!
Uint8List image = Uint8List.fromList(blob.toBytes());
Image.memory(image);
This function has always saved me for getting bytes from a file that is uploaded to a URL.
import 'package:http/http.dart' as http;
// urlImageBlob is the URL where our file is hosted.
Uint8List fileBytes = await http.readBytes(Uri.parse(urlImageBlob));
// Display if are image.
Image.memory(fileBytes);

How to save images from assets to the internal storage in flutter?

I am trying to save the image from assets to internal storage. But, I could not load the image from assets to file. Here is what I have done:
onTap: () async {
final String documentPath = (await getApplicationDocumentsDirectory()).path;
String imgPath = (galleryItems[currentIndex].assetName).substring(7);
File image = await getImageFileFromAssets(imgPath);
print(image.path);
}
I used substring(7) to eliminate assets/ as, my assetName comes as assets/images/foo.jpg.
Future<File> getImageFileFromAssets(String path) async {
final byteData = await rootBundle.load('assets/$path');
final file =
await File('${(await getApplicationDocumentsDirectory()).path}/$path')
.create(recursive: true);
await file.writeAsBytes(byteData.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
return file;
}
After I get image, I don't know how to proceed forward to create a directory with my name in internal storage. And, copy file there.
*Note:- I have editted the post, as some basic mistakes were pointed out.
Update
Here is what I came up with. And it saves image in the /storage/emulated/0/Android/data/com.example.my_project/files/Pics/foo.jpg path.
File image = await getImageFileFromAssets(imgPath);
final extDir = await getExternalStorageDirectory();
// Path of file
final myImagePath = '${extDir.path}/Pics';
// Create directory inside where file will be saved
await new Directory(myImagePath).create();
// File copied to ext directory.
File newImage =
await image.copy("$myImagePath/${basename(imgPath)}");
print(newImage.path);
Here are some links that really helped me:
Flutter How to save Image file to new folder in gallery?
How to Save Image File in Flutter ? File selected using Image_picker plugin
How to convert asset image to File?
Special thanks to #David for the help. Please see comments to understand full scene if you are here to solve your similar problem.
So, I am accepting the answer from #David.
You are trying to create a file object in a path that doesn't exist. You're using your asset path, the path relative to the root of your Flutter project. However, this path doesn't exist in the device's documents folder, so the file can't be created there. The file also doesn't exist in the assets folder because you're prepending the documents path.
To fix your issue, you should pass assetName to rootBundle.load(), without the documents path and open the File() somewhere like $documentPath/foo.jpg
Edit:
To create the file you still have to call File.create, so you need to run:
final file = await File('$documentPath/images/foo.jpg').create(recursive: true);
For future reference, this is just to update the solution of #Biplove which really helped me a lot as a newbie...
Future<File> getImageFileFromAssets(String unique, String filename) async {
ByteData byteData = await rootBundle.load(assets/filename));
// this creates the file image
File file = await File('$imagesAppDirectory/$filename').create(recursive: true);
// copies data byte by byte
await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
return file;
}
Thanks.

Fetch image from URL and convert it to base64 string - Flutter

I've an array of string containing 5 image urls. I'm looking out for a way to fetch the image from url, then encode the image as base64 string, and finally insert that to another array.
The solution should work for both mobile and web in flutter. I was digging around for the solution and got some tricks using File.readAsBytes, Image.toBase64String, etc., but none of them worked on my side.
Finally I found the solution using http package
import 'package:http/http.dart' as http;
Future<String> networkImageToBase64(String imageUrl) async {
http.Response response = await http.get(imageUrl);
final bytes = response?.bodyBytes;
return (bytes != null ? base64Encode(bytes) : null);
}
Example:
final imgBase64Str = await networkImageToBase64('IMAGE_URL');
print(imgBase64Str);
This is working perfectly for both mobile and web.

Flutter: Copy image file from url to firebase

I'm trying to copy a user profile picture from an external service onto my firebase server. So far I have:
final File file = await new File.fromUri(Uri.parse(auth.currentUser.photoUrl)).create();
final StorageReference ref = FirebaseStorage.instance.ref().child("profile_image_${auth.currentUser.uid}.jpg");
final StorageUploadTask uploadTask = ref.put(file);
final Uri downloadUrl = (await uploadTask.future).downloadUrl;
// add user profile picture url to user object
final userReference = FirebaseDatabase.instance
.reference()
.child('users/' + auth.currentUser.uid);
userReference.set({'photoUrl': downloadUrl});
The very top line gives me the error: Unsupported operation: Cannot extract a file path from a https URI
What is the correct way to do this? Should this even be done client-side? (Should I just be passing this url to firebase and use a function to download it server-side?)
File only supports files on a file system.
To load content using HTTP use the http package.
See also https://flutter.io/networking/
var httpClient = createHttpClient();
var response = await httpClient.get(url);
and then get the data from response.body,
or
var response = await httpClient.readBytes(url);
to get it as binary (Uint8List)
See also https://www.dartdocs.org/documentation/http/0.11.3+14/http/Client-class.html

Send an image rather than a link

I'm using the Microsoft Bot Framework with Cognitive Services to generate images from a source image that the user uploads via the bot. I'm using C#.
The Cognitive Services API returns a byte[] or a Stream representing the treated image.
How can I send that image directly to my user? All the docs and samples seem to point to me having to host the image as a publically addressable URL and send a link. I can do this but I'd rather not.
Does anyone know how to simple return the image, kind of like the Caption Bot does?
You should be able to use something like this:
var message = activity.CreateReply("");
message.Type = "message";
message.Attachments = new List<Attachment>();
var webClient = new WebClient();
byte[] imageBytes = webClient.DownloadData("https://placeholdit.imgix.net/~text?txtsize=35&txt=image-data&w=120&h=120");
string url = "data:image/png;base64," + Convert.ToBase64String(imageBytes)
message.Attachments.Add(new Attachment { ContentUrl = url, ContentType = "image/png" });
await _client.Conversations.ReplyToActivityAsync(message);
The image source of HTML image elements can be a data URI that contains the image directly rather than a URL for downloading the image. The following overloaded functions will take any valid image and encode it as a JPEG data URI string that may be provided directly to the src property of HTML elements to display the image. If you know ahead of time the format of the image returned, then you might be able to save some processing by not re-encoding the image as JPEG by just returning the image encoded as base 64 with the appropriate image data URI prefix.
public string ImageToBase64(System.IO.Stream stream)
{
// Create bitmap from stream
using (System.Drawing.Bitmap bitmap = System.Drawing.Bitmap.FromStream(stream) as System.Drawing.Bitmap)
{
// Save to memory stream as jpeg to set known format. Could also use PNG with changes to bitmap save
// and returned data prefix below
byte[] outputBytes = null;
using (System.IO.MemoryStream outputStream = new System.IO.MemoryStream())
{
bitmap.Save(outputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
outputBytes = outputStream.ToArray();
}
// Encoded image byte array and prepend proper prefix for image data. Result can be used as HTML image source directly
string output = string.Format("data:image/jpeg;base64,{0}", Convert.ToBase64String(outputBytes));
return output;
}
}
public string ImageToBase64(byte[] bytes)
{
using (System.IO.MemoryStream inputStream = new System.IO.MemoryStream())
{
inputStream.Write(bytes, 0, bytes.Length);
return ImageToBase64(inputStream);
}
}

Resources