upload Image to firebase storage and NOT File - flutter

There are lot of references of uploading a dart:io 'File' but I want to upload a material.dart Image to firebase.
My Image comes from a processed Thumbnail of a video and not just picked by a Image picker.
This is how I generate a thumbnail,
Future<ThumbnailResult> genThumbnail(url) async {
//WidgetsFlutterBinding.ensureInitialized();
Uint8List bytes;
final Completer<ThumbnailResult> completer = Completer();
bytes = await VideoThumbnail.thumbnailData(
video: url,
imageFormat: ImageFormat.JPEG,
maxHeight: 250,
maxWidth: 300,
timeMs: 0,
quality: 0);
int _imageDataSize = bytes.length;
print("image size: $_imageDataSize");
final _image = Image.memory(bytes);
//final _file =File.fromRawPath(bytes);
_image.image
.resolve(ImageConfiguration())
.addListener(ImageStreamListener((ImageInfo info, bool _) {
completer.complete(ThumbnailResult(
image: _image,
dataSize: _imageDataSize,
height: info.image.height,
width: info.image.width,
));
}));
return completer.future;
}
and this is how File is uploaded to firebase
String Thumbfileurl = await uploadFile(thumbResult.image, fileName, fileType);
And inside uploadFile()
final StorageUploadTask uploadTask = storageReference.putFile(file);
So as you see , A File is needed , but i have an Image , is there a way to Convert Image to File or is there any workaround to achieve this .

Related

Invalid data displaying image from path

I am downloading an image from Internet to the device and then updating a SQLITE table to store the image path:
Future<void> _download(String archivo, String docId, OfertaDB doc) async {
final docUrl = Constantes.docsProyecto+archivo;
final response = await http.get(Uri.parse(docUrl));
// Get the image name
final imageName = path.basename(docUrl);
// Get the document directory path
final appDir = await getApplicationDocumentsDirectory();
// This is the saved image path
// You can use it to display the saved image later
final localPath = path.join(appDir.path, imageName);
// Downloading
final imageFile = File(localPath);
await imageFile.writeAsBytes(response.bodyBytes);
print("path de ofertas ${appDir.path}/${imageName}");
var documentoDescargado = OfertaDB(
id: doc.id,
header: doc.header,
estado: doc.estado,
titulo: doc.titulo,
titulofr: doc.titulofr,
texto: doc.texto,
textofr: doc.textofr,
fechas: doc.fechas,
imagen: doc.imagen,
path: "${appDir.path}/${imageName}"
);
await dbHelper.updateOferta(documentoDescargado);
}
Then on another screen I need to display the image from SQLITE table:
var pathAr = news_promos.path;
print("path es ${pathAr}");//output /data/user/0/red.faro.labelconciergeflutter/app_flutter/Ezg7a9joalimaldivesvilla.jpeg
File image = File(pathAr);
Then to display the image:
Container(
alignment: Alignment.center,
width: 100,
height: 100,
child: image != null
? Image.file(image!, fit: BoxFit.cover)
: const Text('Please select an image'),
),
But the image is not displayed, it is shown an Exception: invalid image data error
What is wrong in the code used?

how to convert blob url to base64 in flutter web?

I use image_picker: ^0.8.5+3 for upload image in web flutter.
Future _imgFromGallery() async {
final image = await picker.pickImage(
source: ImageSource.gallery, maxWidth: 800, maxHeight: 800);
}
But when I print image.path the uploaded photo, it shows me this address with 'blob' blob 'http://localhost:22808/8108f482-37c1-4b7f-9e9c-9e65d1810f5a'
I want to convert image to base64 and for this I use the following code. But this conversion is not done correctly and completely.Can you help me in this matter?
final bytes = html.File(image.path.codeUnits, image.path);
Uint8List b = Uint8List(bytes.toString().length);
String img64 = Base64Encoder().convert(b);
‍‍‍
I found the solution to my problem. I had to add the ‍‍image_picker_for_web: ^2.1.8 and convert the photo to Base64 with the code below:
var image = await picker.pickImage(
source: ImageSource.gallery, maxWidth: 800, maxHeight: 800);
var imageForWeb = await image.readAsBytes();
String base64Image = base64Encode(imageForWeb);

Invalid image on Creating thumbnails from video with flutter

Trying to generate an Thumbnail image from video , the file is created but , errors as Invalid image on load .Using this package video_thumbnail
Creating thumbnail ,
Future<File> genThumbnail(url) async {
//WidgetsFlutterBinding.ensureInitialized();
Uint8List bytes;
final Completer<ThumbnailResult> completer = Completer();
bytes = await VideoThumbnail.thumbnailData(
video: url,
imageFormat: ImageFormat.JPEG,
maxHeight: 250,
maxWidth: 300,
timeMs: 0,
quality: 0);
int _imageDataSize = bytes.length;
print("image size: $_imageDataSize");
//final _image = Image.memory(bytes);
//var _file =File.fromRawPath(bytes);
Directory tempDir = await getTemporaryDirectory();
var uint8list = bytes;
var buffer = uint8list.buffer;
ByteData byteData = ByteData.view(buffer);
File file = await File('${tempDir.path}/img/THUMBNAIL${DateTime.now().toIso8601String()}.JPEG').writeAsBytes(
buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
return file;
}
Saving to firestore
await genThumbnail(fileurl).then((_thumbFIle) async{
String Thumbfileurl = await uploadFile(_thumbFIle, 'thumbnailOf${filenamewithoutExtension}.JPEG', 'videothumbnail');
await sendFileToFirestoreChat(fileType, fileurl, filenamewithoutExtension,Thumbfileurl);
return fileurl;
});
The Saved Image ,
https://firebasestorage.googleapis.com/v0/b/proj-inhouse.appspot.com/o/videos%2Fvideothumbnails%2FthumbnailOfVID-20210301-WA0006.JPEG?alt=media&token=fa4f23c1-601f-486b-97d1-c63e221166af
Posting this as a Community Wiki as it's based on #pskink comments.
To resolve, add the writeAsBytes(bytes) instead of writeAsBytes(buffer.asUint8List()). There is no need for any buffer.

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;
}
}