How to convert an Image instance to File instance in Flutter? - flutter

I am using VideoThumbanil class to fetch an Uint8List image of a video like this:
final uint8List = await VideoThumbnail.thumbnailData(video: videoFile.path,);
After doing so, i am converting the Uint8LIST to an Image using the following code:
Image image = Image.memory(uint8List);
What I want to do is to convert this image to a File class instance so that I can upload this image to my server. Code for uploading on server is:
void asyncFileUpload(File file) async {
//create multipart request for POST or PATCH method
var request = http.MultipartRequest("POST", Uri.parse("127.0.0.1/upload"));
//create multipart using filepath, string or bytes
var pic = await http.MultipartFile.fromPath("image", file.path);
//add multipart to request
request.files.add(pic);
var response = await request.send();
//Get the response from the server
var responseData = await response.stream.toBytes();
var responseString = String.fromCharCodes(responseData);
print(responseString);
}

You can fetch the path to the temporary directory:
final tempDir = await getTemporaryDirectory();
After doing so, you can create a File in that temporary directory:
File fileToBeUploaded = await File('${tempDir.path}/image.png').create();
This way your file has a path and it's instance has been created. Now, you can write the file as:
fileToBeUploaded.writeAsBytesSync(uint8List);
Now, you can use fileToBeUploaded as File that is actually an image.
Complete code:
final uint8List = await VideoThumbnail.thumbnailData(video: videoFile.path,);
final tempDir = await getTemporaryDirectory();
File fileToBeUploaded = await File('${tempDir.path}/image.png').create();
fileToBeUploaded.writeAsBytesSync(uint8List);
asyncFileUpload(fileToBeUploaded);

Since you already have the uint8 list you can try
File fileTpSend = File.fromRawPath(Uint8List uint8List);

Based on your code you need to import 'dart:io' and user fromRawPath function from File class (check snippet below)
import 'dart:io';
final uint8List = await VideoThumbnail.thumbnailData(video:videoFile.path);
final imageAsFile = File.fromRawPath(uint8List);
await asyncFileUpload(imageAsFile);
But this method doesn't work for Flutter WEB

Related

how to upload image to the server against different key using MultupartFile in Flutter..?

suppose you have to upload image to the Server using MultipartFile for a single key like "image". you can easily can do it but if you have different types of keys for file like
"image", "logo", "banner" etc
so how can you handle this for different types keys..
it is working for single key like "image"
final request = http.MultipartRequest('PUT', url,);
request.fields.addAll(body.toMap());
request.headers.addAll(headers);
if (body.image.isNotEmpty) {
final file = await http.MultipartFile.fromPath('image', body.image);
request.files.add(file);
}
Add additional fields if needed
request.fields['field1'] = 'value1';
request.fields['field2'] = 'value2';
full code
import 'dart:io';
import 'package:http/http.dart' as http;
uploadImage(File imageFile) async {
final url = 'http://example.com/upload-image';
var request = http.MultipartRequest('POST', Uri.parse(url));
// Create a MultipartFile from the image file
var image = await http.MultipartFile.fromPath('image', imageFile.path);
// Attach the MultipartFile to the MultipartRequest
request.files.add(image);
// Add additional fields if needed
request.fields['field1'] = 'value1';
request.fields['field2'] = 'value2';
// Send the MultipartRequest to the server
var response = await request.send();
// Check the response status code
if (response.statusCode == 200) {
// Image upload successful
print('Image uploaded successfully');
} else {
// Image upload failed
print('Image upload failed with status ${response.statusCode}');
}
}
I think this will help you

How to print a PDF file in Flutter

Here is my code
Future<File> _downloadFile(String url, String filename) async {
http.Client _client = new http.Client();
var req = await _client.get(Uri.parse(url));
var bytes = req.bodyBytes;
// String dir = (await getApplicationDocumentsDirectory()).path;
String dir = await ExtStorage.getExternalStoragePublicDirectory(
ExtStorage.DIRECTORY_DOWNLOADS);
File file = new File('$dir/$filename');
await file.writeAsBytes(bytes);
return file;
}
/// Prints a sample pdf printer
void printPdfFile() async {
var file = await _downloadFile(
"http://www.africau.edu/images/default/sample.pdf", "test.pdf");
await FlutterPdfPrinter.printFile(file.path);
}
I am implementing print PDF files which is saved in my device. When trying to print the document I am getting error like "A problem occurred configuring project ':flutter_pdf_printer'."
I am using flutter_pdf_printer dependency to print PDF files.
Convert your string url to URI, please make sure you are adding http
http: ^0.13.4
import 'package:http/http.dart' as http;
Uri uri = Uri.parse('Your link here');
http.Response response = await http.get(uri);
var pdfData = response.bodyBytes;
await Printing.layoutPdf(onLayout: (PdfPageFormat
format) async => pdfData);

How to add local image to flutter_local_notifications

I am trying to create push notifications and would like to add an image to the notification. I am able to add images from the web as shown in the screenshot below.
How can I add a local image instead? I tried adding the file path as shown below, but it did not work:
The file path you are adding is a root path of your project but this method needs an android file path(e.g. /storage/emulated/0/Android/data/com.expampe.app/cache/bg.png), so you have to convert your asset image to a File and save it, then return its path:
import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart' show rootBundle;
import 'package:path_provider/path_provider.dart';
Future<String> getImageFilePathFromAssets(String asset) async {
final byteData = await rootBundle.load(asset);
final file =
File('${(await getTemporaryDirectory()).path}/${asset.split('/').last}');
await file.writeAsBytes(byteData.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
return file.path;
}
then just
final attachmentPicturePath = await getImageFilePathFromAssets('assets/image2.jpg');
The Easiest Way is--
static Future<String> getImageFilePathFromAssets(
String asset, String filename) async {
final byteData = await rootBundle.load(asset);
final temp_direactory = await getTemporaryDirectory();
final file = File('${temp_direactory.path}/$filename');
await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes,
byteData.lengthInBytes));
return file.path;
}
final bigpicture = await Utils.getImageFilePathFromAssets(
'assets/images/largicon.png', 'bigpicture');
And For donwload Using URL---
add http and path_provider in pubspec.yml
static Future<String> downloadFile(String URL, String filename) async
{
final direactory = await getApplicationSupportDirectory();
final filepath = '${direactory.path}/$filename';
final response = await http.get(Uri.parse(URL));
print(response);
final file = File(filepath);
await file.writeAsBytes(response.bodyBytes);
return filepath;
}
check this demo github

Flutter cannot get download url firebase-storage

While trying to upload byteArray to the bucket in firebase storage, the file uploads to the storage but I cannot get the downloadUrl back from the file. I am getting the reference of bucket like this:
Future<Reference> get storageRef async {
final _bucketUrl = await bucketUrl;
return FirebaseStorage.instanceFor(bucket: _bucketUrl).ref();
}
And Uploading image like this:
Future<String> uploadImageByteArray({
#required Uint8List byteArray,
String fileName,
}) async {
final name = fileName ?? DateTime.now().toIso8601String();
final _ref = await storageRef;
final _refUrl = _ref.child("images/$name.png");
print(_refUrl.fullPath);
final uploadTask = _refUrl.putData(byteArray);
final snapshot = await uploadTask;
return snapshot.ref.getDownloadURL();
}
From above code I am getting this error:
Unhandled Exception: type 'NoSuchMethodError' is not a subtype of type 'Exception'.
It works if I get reference for the FirebaseStorage only and not the bucket like this:
Future<Reference> get storageRef{
return FirebaseStorage.instance.ref();
}
I cannot implement without using bucket reference because there can be different bucket urls depending on the tenants. What am I doing wrong?
Edit => Recent Developments:
I found out that it works if I get the downloadurl from the _refUrl itself. i.e:
String downloadUrl = _refUrl.getDownloadUrl();
It works but I can't help but wonder if it is correct implementation.
Your edit makes perfect sense since you have the reference to the uploaded file with _refUrl, fetching its long-lived download URL works as expected (That's how I have done it before btw). I don't have access to a project with FirebaseStorage to test this, but You can try printing snapshot.ref.fullPath and compare it with the fullPath of _refUrl.
try this
Future<String> uploadImageByteArray({
#required Uint8List byteArray,
String fileName,
}) async {
final name = fileName ?? DateTime.now().toIso8601String();
final _ref = await storageRef;
final _refUrl = _ref.child("images/$name.png");
print(_refUrl.fullPath);
final uploadTask = _refUrl.putData(byteArray);
final snapshot = (await uploadTask);
String url = await snapshot.ref.getDownloadURL(); // await
return url;
}

How to store signature as an image in firebase storage

I have a form, in that form I have a signature pad. I used signature 3.2.0 package. That package consist a method toImage(). I want to store that image in the firebase storage. when I try below code.
fileImage = _controller.toImage() as File;
final FirebaseStorage storage = FirebaseStorage.instance;
final String picture = "${DateTime.now().millisecondsSinceEpoch.toString()}.jpg";
StorageUploadTask task = storage.ref().child(picture).putFile(fileImage);
task.onComplete.then((snapshot) async{
loadData.setSignatureURL = await snapshot.ref.getDownloadURL();
});
loadData.storeDetails();
I got an error type 'Image' is not a subtype of type 'File' in type cast.
How can I store signature as an image/
Casting can't be done on a whim, which is why you get this error.
The Image class provides a toByteData method that allows you to retrieve the raw image data as a ByteData object. You can then convert this to a Uint8List. This list then can be directly used for firebase storage with the putData method instead of putFile.
var image = await _controller.toImage();
ByteData data = await image.toByteData();
Uint8List listData = data.buffer.asUint8List();
final FirebaseStorage storage = FirebaseStorage.instance;
final String picture = "${DateTime.now().millisecondsSinceEpoch.toString()}.jpg";
StorageUploadTask task = storage.ref().child(picture).putData(listData);
...
If you need to encode this image to a specific type. You can use a version of the following code which encodes to JPG. It uses the image package which needs to be added as a dependency
import 'package:image/image.dart' as encoder;//This import needs to be added in the file this is being done
var image = await _controller.toImage();
//Store image dimensions for later
int height = image.height;
int width = image.width;
ByteData data = await image.toByteData();
Uint8List listData = data.buffer.asUint8List();
encoder.Image toEncodeImage = encoder.Image.fromBytes(width, height, listData);
encoder.JpegEncoder jpgEncoder = encoder.JpegEncoder();
List<int> encodedImage = jpgEncoder.encodeImage(toEncodeImage);
final FirebaseStorage storage = FirebaseStorage.instance;
final String picture = "${DateTime.now().millisecondsSinceEpoch.toString()}.jpg";
StorageUploadTask task = storage.ref().child(picture).putData(Uint8List.fromList(encodedImage));
...