I'm using qr_flutter to create QrImage. It's ok but I would like to convert QrImage into image in order to create a PDF file to print on the printer. Please kindly help!
QrImage(
data: qrString,
size: 300.0,
version: 10,
backgroundColor: Colors.white,
),
Use a RepaintBoundary widget with a key to export the widget to a a b64 string which then you can export as an image.
Example:
Future<Uint8List> _getWidgetImage() async {
try {
RenderRepaintBoundary boundary =
_renderObjectKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage(pixelRatio: 3.0);
ByteData byteData =
await image.toByteData(format: ui.ImageByteFormat.png);
var pngBytes = byteData.buffer.asUint8List();
var bs64 = base64Encode(pngBytes);
debugPrint(bs64.length.toString());
return pngBytes;
} catch (exception) {}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(children: [
RepaintBoundary(
key: _renderObjectKey,
child: QrImage(
data: "some text",
size: 300.0,
version: 10,
backgroundColor: Colors.white,
),
),
RaisedButton(onPressed: () {
_getWidgetImage();
})
]));
}
Future<Uint8List> toQrImageData(String text) async {
try {
final image = await QrPainter(
data: text,
version: QrVersions.auto,
gapless: false,
color: hexToColor('#000000'),
emptyColor: hexToColor('#ffffff'),
).toImage(300);
final a = await image.toByteData(format: ImageByteFormat.png);
return a.buffer.asUint8List();
} catch (e) {
throw e;
}
}
A more updated typed answer, that adds responsibility seggregation and null-safety, extending the correct one from #Zroq would be:
Future<Uint8List> createImageFromRenderKey({GlobalKey<State<StatefulWidget>>? renderKey}) async {
try {
final RenderRepaintBoundary boundary = renderKey?.currentContext?.findRenderObject()! as RenderRepaintBoundary;
final ui.Image image = await boundary.toImage(pixelRatio: 3);
final ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
return byteData!.buffer.asUint8List();
} catch(_) {
rethrow;
}
}
The idea is based on the same principle: using the global render key to create the ByteData that allows you to create the Uint8List buffer. However, the new versions of Flutter change the type of the boundary to become a RenderyObject? instead of a RenderRepaintBoundary.
The rethrow is (dirty) way of bypassing the limitation/small bug where RepaintBoundary may be being used in the UI to repaint the boundary (exposed as boundary.debugNeedsPaint), so it can potentially throw an unhandled exception or create a low-quality image buffer. So if the view is being used I rethrow the method.
More details about the stack trace: https://github.com/theyakka/qr.flutter/issues/112
Related
How to upload images in server using flutter with Laravel API? I tried using getx, its returning null. also I have image_picker and image_cropper package in my pubspec.yaml
Select Image from Gallery using File Picker
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
class ImageScreen extends StatefulWidget {
ImageScreen();
#override
State<ImageScreen> createState() => _ImageScreenState();
}
class _ImageScreenState extends State<ImageScreen> {
File file;
Future<File> uploadImage() async {
FilePickerResult result = await FilePicker.platform.pickFiles();
if (result != null) {
setState(() {
file = File(result.files.single.path);
});
print(result.files.single.path);
} else {
// User canceled the picker
}
return file;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onTap: () {
uploadImage();
},
child: Container(
color: Colors.green,
padding: EdgeInsets.all(5),
child: Text('Upload Image', style: TextStyle(fontSize: 16, color: Colors.white),)
),
),
);
}
}
Uploading Image to the server using http.multipartFile
static Future<dynamic> uploadImage({File file}) async {
try {
http.MultipartRequest request = new http.MultipartRequest("POST", _uri);
http.MultipartFile multipartFile = await http.MultipartFile.fromPath('file_name', file.path);
request.files.add(multipartFile);
var streamedResponse = await request.send();
var response = await http.Response.fromStream(streamedResponse);
if (response.statusCode == 200 ) {
return jsonDecode(response.body);
}
}
catch (e) {
return null;
}
}
final images = <File>[].obs;
Use this method for picking up images
Future pickImage(ImageSource source) async {
ImagePicker imagePicker = ImagePicker();
XFile pickedFile = await imagePicker.pickImage(source: source, imageQuality: 80);
File imageFile = File(pickedFile.path);
print(imageFile);
if (imageFile != null) {
images.add(imageFile);
} else {
Get.showSnackbar(GetSnackBar(message: "Please select an image file"));
}
}
Use this for uploading images to the server with your specific url.As I have used dio for uploading.You can use http as well.
Future<String> uploadImage(File file) async {
String fileName = file.path.split('/').last;
// you can edit it for your own convenience
var _queryParameters = {
'api_token': 'your token if required',
};
Uri _uri = 'Your base url'
var formData = FormData.fromMap({
"file": await MultipartFile.fromFile(file.path, filename: fileName),
});
var response = await dio.post(_uri, data: formData);
print(response.data);
if (response.data['data'] != false) {
return response.data['data'];
} else {
throw new Exception(response.data['message']);
}
}
This works for me, so maybe others might need it as well.
uploadImage(imageFile) async {
var stream = new http.ByteStream(
DelegatingStream.typed(imageFile.openRead()));
var length = await imageFile.length();
var uri = Uri.parse(
'http://192.168.5.196/ApiFileUploadTest/public/api/uploading-file-api');
var request = new http.MultipartRequest('POST', uri);
var multipartFile = new http.MultipartFile('file', stream, length,
filename: basename(imageFile.path));
request.files.add(multipartFile);
var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}
how can I convert the Uint8List imagedata of the Screenshot Package to save it with the ImageGallerySaver package saveFile command, which needs a string?
TextButton(
onPressed: () {
_imageFile = null;
screenshotController
.capture()
.then((Uint8List image) async {
//print("Capture Done");
setState(() {
_imageFile = image;
});
final result = await ImageGallerySaver.saveFile();
print("File Saved to Gallery");
}).catchError((onError) {
print(onError);
});
I found a solution:
TextButton(
onPressed: () {
_imageFile = null;
screenshotController
.capture()
.then((Uint8List image) async {
//print("Capture Done");
String dir =
(await getApplicationDocumentsDirectory()).path;
File file = File("$dir/" +
DateTime.now().millisecondsSinceEpoch.toString() +
".png");
await file.writeAsBytes(image);
setState(() {
_imageFile = image;
});
final result =
await ImageGallerySaver.saveFile(file.path);
print("File Saved to Gallery");
}).catchError((onError) {
print(onError);
});
},
child: Icon(Icons.change_history),
), // Thi
I have the following code where I fetch an image from firebase storage as an Image. Now, I want to store this image in my CachedNetworkImage so that I don't have to fetch it every time from the DB. Since the cachednetworkimage expects a URL and I am fetching an Image, how do I use the cachednetworkimage?
Here's my code;
final FirebaseStorage storage = FirebaseStorage(
app: Firestore.instance.app,
storageBucket: 'gs://my-project.appspot.com');
Uint8List imageBytes;
String errorMsg;
_MyHomePageState() {
storage.ref().child('selfies/me2.jpg').getData(10000000).then((data) =>
setState(() {
imageBytes = data;
})
).catchError((e) =>
setState(() {
errorMsg = e.error;
})
);
}
#override
Widget build(BuildContext context) {
var img = imageBytes != null ? Image.memory(
imageBytes,
fit: BoxFit.cover,
) : Text(errorMsg != null ? errorMsg : "Loading...");
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new ListView(
children: <Widget>[
img,
],
));
}
}```
Cached network image and Flutter cache manager
The package Cached network image depends on another package called Flutter cache manager in order to store and retrieve image files.
Flutter cache manager
You need to download your image files and put them in the cache using the package. Here is an example code that gets files and their download urls from Firebase Storage and put them in the cache:
// import the flutter_cache_manager package
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
// ... other imports
class MyCacheManager {
Future<void> cacheImage() async {
final FirebaseStorage storage = FirebaseStorage(
app: Firestore.instance.app,
storageBucket: 'gs://my-project.appspot.com',
);
final Reference ref = storage.ref().child('selfies/me2.jpg');
// Get your image url
final imageUrl = await ref.getDownloadURL();
// Download your image data
final imageBytes = await ref.getData(10000000);
// Put the image file in the cache
await DefaultCacheManager().putFile(
imageUrl,
imageBytes,
fileExtension: "jpg",
);
}
}
Cached network image
Next, you will use CacheNetworkImage widget as it shown in the documentation.
// ... some code
#override
Widget build(BuildContext context) {
return Scaffold(
body: CachedNetworkImage(
imageUrl: "your_image_link_here",
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
);
}
If you put your image files in the cache by using Flutter cache manager, Cached network image should retrieve them from the cache directly. If your image files expire or the cache is cleared somehow, it will download and put them in the cache for you.
Full Example
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
class MyCacheManager {
final _storage = FirebaseStorage(
app: FirebaseFirestore.instance.app,
storageBucket: 'gs://my-project.appspot.com',
);
final defaultCacheManager = DefaultCacheManager();
Future<String> cacheImage(String imagePath) async {
final Reference ref = _storage.ref().child(imagePath);
// Get your image url
final imageUrl = await ref.getDownloadURL();
// Check if the image file is not in the cache
if ((await defaultCacheManager.getFileFromCache(imageUrl))?.file == null) {
// Download your image data
final imageBytes = await ref.getData(10000000);
// Put the image file in the cache
await defaultCacheManager.putFile(
imageUrl,
imageBytes,
fileExtension: "jpg",
);
}
// Return image download url
return imageUrl;
}
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _imageUrl;
#override
void initState() {
final myCacheManager = MyCacheManager();
// Image path from Firebase Storage
var imagePath = 'selfies/me2.jpg';
// This will try to find image in the cache first
// If it can't find anything, it will download it from Firabase storage
myCacheManager.cacheImage(imagePath).then((String imageUrl) {
setState(() {
// Get image url
_imageUrl = imageUrl;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: _imageUrl != null
? CachedNetworkImage(
imageUrl: _imageUrl,
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
)
: CircularProgressIndicator(),
),
);
}
}
Try this way out using firebase_image package. From here . You need to sync with image url (selfies/me2.jpg) and bucket url (gs://my-project.appspot.com)
Image(
image: FirebaseImage('gs://bucket123/userIcon123.jpg'),
// Works with standard parameters, e.g.
fit: BoxFit.fitWidth,
width: 100,
// ... etc.
)
I'm not Fire-store user, but this should work.
It might needs a little modification or something, please share in a comment to update my answer according to that
You can get file object as follow..
import 'dart:io';
import 'dart:typed_data';
Uint8List readyData = imageBytes;
File('my_image.jpg').writeAsBytes(bodyBytes);
and save it using image_gallery_saver, so the code should look like
Future<String> _createFileFromString() async {
final encodedStr = "...";
Uint8List bytes = base64.decode(imageBytes);
String dir = (await getApplicationDocumentsDirectory()).path;
String fullPath = '$dir/abc.png';
print("local file full path ${fullPath}");
File file = File(fullPath);
await file.writeAsBytes(bytes);
print(file.path);
final result = await ImageGallerySaver.saveImage(bytes);
print(result);
return file.path;
}
For your storage instance use some method like so
Future<void> downloadURLExample() async {
String downloadURL = await storage.ref('selfies/me2.jpg')
.getDownloadURL();
// Within your widgets:
// CachedNetworkImage(imageUrl: downloadURL);
}
to get it working with Firebase Storage with included offline functionality I changed it that way
Future<String> cacheImage(String imagePath) async {
var fileinfo = await defaultCacheManager.getFileFromCache(imagePath);
if(fileinfo != null)
{
return fileinfo.file.path;
} else{
final Reference ref = _storage.child(imagePath);
// Get your image url
final imageUrl = await ref.getDownloadURL();
// Check if the image file is not in the cache
// Download your image data
final imageBytes = await ref.getData(10000000);
// Put the image file in the cache
var file = await defaultCacheManager.putFile(
imageUrl,
imageBytes!,
key: imagePath,);
return file.path;
}
}
for anyone still stuck with this.. try this required no hacks and uses CachedNetworkImageProvider built-in retrieval methods.
first screen:
CachedNetworkImage(
imageUrl: "https://whereismyimage.com",
progressIndicatorBuilder:
(context, url, progress) {
return CircularProgressIndicator(
value: progress.progress,
);
},
errorWidget: (context, url, error) => const Icon(Icons.error),
),
then second screen
Image(image: CachedNetworkImageProvider("https://whereismyimage.com)"),
The CachedNetworkImageProvider knows how to retrieve the cached image using the url.
Check out cached_network_image: ^2.5.0 package.
How to use it?
CachedNetworkImage(
imageUrl: "http://via.placeholder.com/350x150",
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
I am making a face in flutter using different facial images and i want to export it as jpg when the face creation is done. what could i use to achieve it?
You can see here a face is created and i want to export only face as a jpeg.
In this article, use GlobalKey with your widget and save image by following code:
takeScreenShot() async {
RenderRepaintBoundary boundary =
previewContainer.currentContext.findRenderObject();
double pixelRatio = originalSize / MediaQuery.of(context).size.width;
ui.Image image = await boundary.toImage(pixelRatio: pixelRatio);
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData.buffer.asUint8List();
setState(() {
_image2 = Image.memory(pngBytes.buffer.asUint8List());
});
final directory = (await getApplicationDocumentsDirectory()).path;
File imgFile = new File('$directory/screenshot.png');
imgFile.writeAsBytes(pngBytes);
final snackBar = SnackBar(
content: Text('Saved to ${directory}'),
action: SnackBarAction(
label: 'Ok',
onPressed: () {
// Some code
},
),
);
Scaffold.of(context).showSnackBar(snackBar);
}
I'm calling a widget in my code to display the selected image through image-picker plugin; following is my code:
Widget _imagePlaceHolder() {
if (imageSelected == null){
return Text("No File Selected!!");
} else {
Image.file(imageSelected, width: 400, height: 400);
}
}
but I'm getting this error:
The argument type "'PickedFile'" can't be assigned to the parameter type 'File'
on imageSelected under else statement.
I'm picking an image like this from gallery:
Future _openGallery(BuildContext context) async {
var picture = await picker.getImage(source: ImageSource.gallery);
this.setState(() {
imageSelected = picture;
});}
I've defined:
PickedFile imageSelected;
final picker = ImagePicker();
what's going wrong here? Please help..
Image.file() accepts a property of type File class, whereas the ImagePicker().getImage() method returns a type PickedFile.
We have to utilise the getter .path of the returned PickedFile argument and pass that file path to the create a File object as follows:
void _setImage() async {
final picker = ImagePicker();
PickedFile pickedFile = await picker.getImage(source: ImageSource.gallery);
imageFile = File(pickedFile.path);
}
This may be done in one line as follows:
void _setImage() async {
imageFile = File(await ImagePicker().getImage(source: ImageSource.gallery).then((pickedFile) => pickedFile.path));
}
After this, you can use the variable imageFile and pass it inside Image.file() like Image.file(imageFile), or FileImage() like FileImage(imageFile) as required.
For more, see the image_picker documentation on pub.dev
//many time when user import dart.html package than it throw error so keep note that we have to import dart.io
import 'dart.io';
final imagePicker = ImagePicker();
File imageFile;
Future getImage() async {
var image = await imagePicker.getImage(source: ImageSource.camera);
setState(() {
imageFile = File(image.path);
});
}
Change PickedFile imageSelected to File imageSelected and use ImagePicker.pickImage(source: ImageSource.gallery) instead of picker.getImage(source: ImageSource.gallery);
import 'package:image_picker/image_picker.dart';
import 'dart:io';
var image;
void imagem() async {
PickedFile picked = await ImagePicker().getImage(
preferredCameraDevice: CameraDevice.front, source: ImageSource.camera);
setState(() {
image = File(picked.path);
});
}
Or case you need of code full:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
class Photos extends StatefulWidget {
#override
_PhotosState createState() => _PhotosState();
}
class _PhotosState extends State<Photos> {
var image;
void imagem() async {
PickedFile picked = await ImagePicker().getImage(
preferredCameraDevice: CameraDevice.front, source: ImageSource.camera);
setState(() {
image = File(picked.path);
});
}
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Center(
child: Column(
children: [
RaisedButton(
onPressed: imagem,
child: Text("Imagem"),
),
image != null ? Image.file(image) : Text("I")
],
),
));
}
}
Morpheus answer is correct.
Just pass in the PickedFile variable path to File().
Example:
final picker = ImagePicker();
PickedFile pickedFile = await picker.getImage(source: ImageSource.gallery);
imageFile = File(pickedFile.path);
Try converting your imageFile type to PickedImage and return the file in type Casting the imageFile to File, Like:-
// Declaring the variable here
PickedImage imageFile;
And at the time of returning:-
return Image.file(File(imageFile.path),width: 400,height: 400,);
I personally faced this problem, and this solution solved it.
Try this way...
Future pickImageFromGallery() async {
try {
final pickedFile = await picker.pickImage(
source: ImageSource.gallery,
);
setState(() {
widget.imageFile = File(pickedFile!.path);
});
if (pickedFile == null) {
throw Exception('File is not available');
}
} catch (e) {
print(e);
}