Flutter Converting network image into byteData - flutter

Is there any better way to convert network image to byteData? I am trying to convert network image from firebase url to byteData and here is my code:
Future<Uint8List> _loadNetworkImage() async {
try {
final response = await http.get(imageUrl);
return response.bodyBytes;
} catch (_) {
throw "Couldn't resolve network Image.";
}
}
Currently it takes almost 20+ seconds for a 7mb photo to be converted.

Here is how I ended up doing it.
Future<Uint8List?> _loadNetworkImage(String path) async {
final completer = Completer<ImageInfo>();
var img = NetworkImage(path);
img.resolve(const ImageConfiguration()).addListener(
ImageStreamListener((info, _) => completer.complete(info)));
final imageInfo = await completer.future;
final byteData =
await imageInfo.image.toByteData(format: ui.ImageByteFormat.png);
return byteData?.buffer.asUint8List();
}

Related

ImageCropper use with Uint8List file -flutter

I'm using image_picker & ImageCropper packages. I want to save a user-given picture in firestore database. So, I use functions like this.
First, set File? _image;
Functions for cropping & picking
Future _pickImage(ImageSource source) async {
Navigator.of(context).pop();
try {
final image = await ImagePicker().pickImage(source: source);
if (image == null) return;
File? img = File(image.path);
img = await _cropImage(imageFile: img);
setState(() {
_image = img;
});
} on PlatformException catch (e) {
print(e);
Navigator.of(context).pop();
}
}
Future<File?> _cropImage({required File imageFile}) async {
CroppedFile? croppedImage =
await ImageCropper().cropImage(sourcePath: imageFile.path);
if (CroppedFile == null) return null;
return File(croppedImage!.path);
}
and use this to save data in firestore
Future<String> uploadImageToStorage(
File file,
) async {
file
Reference ref =
_storage.ref().child("profilePics").child(_auth.currentUser!.uid);
UploadTask uploadTask = ref.putData(file);
TaskSnapshot snap = await uploadTask;
String downloadUrl = await snap.ref.getDownloadURL();
return downloadUrl;
}
Above function not work for File type data, It support for Uint8List. So, What can I do for this?
Next problem is, I'm getting File type data with ImagePicker for profile picture. Is it not problem?
Try changing your _cropImage-Method to return XFile? like this:
Future<XFile?> _cropImage({required File imageFile}) async {
CroppedFile? croppedImage =
await ImageCropper().cropImage(sourcePath: imageFile.path);
if (CroppedFile == null) return null;
return XFile(croppedImage!.path);
}
You also have to change the paramter of uploadImageToStorage to XFile file. Then you can use file!.readAsBytes(); to get a Uint8List.
Future<String> uploadImageToStorage(
XFile file,
) async {
Reference ref =
_storage.ref().child("profilePics").child(_auth.currentUser!.uid);
final fileBytes = await file.readAsBytes();
UploadTask uploadTask = ref.putData(fileBytes);
TaskSnapshot snap = await uploadTask;
String downloadUrl = await snap.ref.getDownloadURL();
return downloadUrl;
}

Can I convert Future<Uint8List> to Uint8List in flutter? [duplicate]

This question already has answers here:
What is a Future and how do I use it?
(6 answers)
Closed 3 months ago.
I'm making a watermark image using flutter and I need to convert Future to Uint8List.
This is the code where the problem happens.
child: Image.memory(putWatermarkOnImage(asset))
The child is in the Container widget and the result of the putWatermarkOnImage function has to be Uint8List type not a future type.
Future<Uint8List> putWatermarkOnImage(asset) async {
final assetFile = await asset.file;
var imageBytes = await assetFile!.readAsBytes();
ByteData watermarkImgByteData = await rootBundle.load('assets/images/ournow_logo.png');
Uint8List watermarkImgBytes = watermarkImgByteData.buffer.asUint8List();
Uint8List imageUint8List = Uint8List.fromList(imageBytes);
Uint8List watermarkedImg = await ImageWatermark.addImageWatermark(
originalImageBytes: imageUint8List,
waterkmarkImageBytes: watermarkImgBytes,
imgHeight: 200,
imgWidth: 200,
dstY: 400,
dstX: 400);
return watermarkedImg;
}
How can I solve this problem?
I have taken your code and wrote it the way I do to avoid confusions, so I created a class for you on the side to collect all bytes transformation related methods and called them "BytesHandlers"
then I re-organized the code as follows,,, I believe it will work
please test it and tell me if something is going wrong
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:wechat_camera_picker/wechat_camera_picker.dart';
Future<Uint8List> putWatermarkOnImage(AssetEntity asset) async {
Uint8List _output;
if (asset != null){
final File assetFile = await asset.file;
final ByteData watermarkImgByteData = await BytesHandlers.getByteDataFromPath('assets/images/ournow_logo.png');
_output = await BytesHandlers.getUint8ListFromFile(assetFile);
_output = await ImageWatermark.addImageWatermark(
originalImageBytes: _output,
waterkmarkImageBytes: watermarkImgByteData,
imgHeight: 200,
imgWidth: 200,
dstY: 400,
dstX: 400
);
}
return _output;
}
class BytesHandlers {
// --------------------
BytesHandlers();
// --------------------
static Future<ByteData> getByteDataFromPath(String assetPath) async {
/// NOTE : Asset path can be local path or url
ByteData _byteData;
if (assetPath != null){
_byteData = await rootBundle.load(assetPath);
}
return _byteData;
}
// --------------------
static Future<Uint8List> getUint8ListFromFile(File file) async {
Uint8List _uInt;
if (file != null){
_uInt = await file.readAsBytes();
}
return _uInt;
}
// --------------------
}
then you get to call it like this
final Uint8List _ImageWithWatermark = await putWatermarkOnImage(_inputFile);

Print QR code using esc_pos_printer flutter

I'm using esc_pos_printer package which can print a receipt over network. I need two features
Save a qr/bar code in the gallery
Print said qr/bar code using the thermal printer/regular printer
For saving the qr code I did:
static Future<File> _saveBarCode(GlobalKey key, String productId) async {
print("save bar code");
RenderRepaintBoundary boundary =
key.currentContext!.findRenderObject() as RenderRepaintBoundary;
ui.Image image = await boundary.toImage();
ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData!.buffer.asUint8List();
final tempPath = (await getTemporaryDirectory()).path;
final path = tempPath + "/" + productId + ".png";
File imgFile = File(path);
print(imgFile.path);
return imgFile.writeAsBytes(pngBytes);
}
and
static void save(GlobalKey key, String productId) async {
_saveBarCode(key, productId).then((value) async {
bool? saved = await GallerySaver.saveImage(value.path);
print("saved: $saved");
}).catchError((error) {
print(error);
});
}
But the printing part is giving me trouble:
void printOverNetwork(GlobalKey key, String productId) async {
const PaperSize paperSize = PaperSize.mm80;
final profile = await CapabilityProfile.load();
final printer = NetworkPrinter(paperSize, profile);
final PosPrintResult result =
await printer.connect('192.168.0.123', port: 9100);
_saveBarCode(key, productId).then((value) {
if (result == PosPrintResult.success) {
// print the qr/barcode
}
});
}
How can I solve the issue?

How to get Download URL from Firebase Storage in flutter

The Following Code is used to Upload any image from gallery/Camera to Firebase storage. I was successful in uploading the image to storage along with meta data. Now the problem is I am not able to get the download URL of the uploaded image. Tried a lot but didn't find any solution.
FirebaseStorage storage = FirebaseStorage.instance;
final picker = ImagePicker();
PickedFile pickedImage;
File imageFile;
Future<void> _upload(String inputSource) async {
try {
pickedImage = await picker.getImage(
source: inputSource == 'camera'
? ImageSource.camera
: ImageSource.gallery,
maxWidth: 1920);
final String fileName = path.basename(pickedImage.path);
imageFile = File(pickedImage.path);
try {
// Uploading the selected image with some custom meta data
await storage.ref(fileName).putFile(
imageFile,
SettableMetadata(
customMetadata: {
'uploaded_by': 'A bad guy',
'description': 'Some description...'
},
),
);
// Refresh the UI
setState(() {});
} on FirebaseException catch (error) {
print(error);
}
} catch (err) {
print(err);
}
}
Hope You're Doing Well …
You Can Try This Method To Get The URL Of The Image(Any File) From Firebase Storage To Firebase Store And Then You Can Retrieve Image .
class _UploadAdState extends State<UploadAdPage> {
final formKey = GlobalKey<FormState>();
File _myimage;
String imgUrl;
Future getImage1(File chosenimage) async {
PickedFile img =
await ImagePicker.platform.pickImage(source: ImageSource.gallery);
if (chosenimage == null) return null;
File selected = File(img.path);
setState(() {
_myimage = chosenimage;
});
}
// changing the firestore rules and deleteing if request.auth != null;
sendData() async {
// to upload the image to firebase storage
var storageimage = FirebaseStorage.instance.ref().child(_myimage.path);
UploadTask task1 = storageimage.putFile(_myimage);
// to get the url of the image from firebase storage
imgUrl1 = await (await task1).ref.getDownloadURL();
// you can save the url as a text in you firebase store collection now
}
}
I am using in my app this function. Pass image file and download with getDownloadUrl .
Future <String> _uploadphotofile(mFileImage) async {
final Reference storageReference = FirebaseStorage.instance.ref().child("products");
UploadTask uploadTask = storageReference.child("product_$productId.jpg").putFile(imgfile);
String url = await (await uploadTask).ref.getDownloadURL();
return url;
}

How to get a Uint8List from a Network image by url in Flutter?

I have the network url of image and I need to get Uint8List. How can I convert it?
I check answers in like question, but those ways don't work.
How to get a Flutter Uint8List from a Network Image?
Try this:
Uint8List bytes = (await NetworkAssetBundle(Uri.parse(url)).load(url))
.buffer
.asUint8List();
Uint8List yourVar;
final DecoderCallback callback = (Uint8List bytes, {int cacheWidth, int cacheHeight}) {
yourVar = bytes.buffer.asUint8List();
return instantiateImageCodec(bytes, targetWidth: cacheWidth, targetHeight: cacheHeight);
};
ImageProvider provider = NetworkImage(yourImageUrl);
provider.obtainKey(createLocalImageConfiguration(context)).then((key) {
provider.load(key, callback);
});
this did the trick for me:
import 'dart:typed_data';
import 'package:flutter/services.dart';
//Get the image from the URL and then convert it to Uint8List
Uint8List bytes = (await NetworkAssetBundle(Uri.parse('https://some_image_url.png'))
.load('https://some_image_url.png'))
.buffer
.asUint8List();
This works on me (using flutter web) with a library file_saver.
Uri uri = Uri.parse(url);
Uint8List bytes = await readBytes(uri);
await FileSaver.instance.saveFile(filename, bytes, 'jpg',
mimeType: MimeType.JPEG); // specify your vars
I'm having the same problem in Flutter web, I had to use the extended_image library, and I found inside your example that has a method that allows you to convert an ImageProvider to Bytes.
https://github.com/fluttercandies/extended_image/blob/master/example/lib/pages/simple/image_editor_demo.dart.
/// it may be failed, due to Cross-domain
Future<Uint8List> _loadNetwork(ExtendedNetworkImageProvider key) async {
try {
final Response response = await HttpClientHelper.get(Uri.parse(key.url),
headers: key.headers,
timeLimit: key.timeLimit,
timeRetry: key.timeRetry,
retries: key.retries,
cancelToken: key.cancelToken);
return response.bodyBytes;
} on OperationCanceledError catch (_) {
print('User cancel request ${key.url}.');
return Future<Uint8List>.error(
StateError('User cancel request ${key.url}.'));
} catch (e) {
return Future<Uint8List>.error(StateError('failed load ${key.url}. \n $e'));
}
}