I am trying to generate an image using RenderRepaintBoundary and want to save the image in my local directory.
I am able to save the image but I get a black image instead of a QR image.
Code block where I am writing the image to the directory:
try {
RenderRepaintBoundary boundary =
globalKey.currentContext.findRenderObject();
var image = await boundary.toImage();
ByteData byteData = await image.toByteData(format: ImageByteFormat.png);
Uint8List pngBytes = byteData.buffer.asUint8List();
final file =
await new File('/<localpath>/image.png').create();
await file.writeAsBytes(pngBytes);
} catch (e) {
print(e);
}
Code block where QR code is being generated:
RepaintBoundary( key: globalKey,child: QrImage(data: _dataString,size: 0.3 * bodyHeight,), );
This is caused by having transparent background;
Simple solution is to wrap your QrImage with Container that has white backround:
Container(
color: Colors.white,
child: QrImage(....
)
Related
I am using the barcode_widget to generate both barcode and 2d QR code. But I also need to print and save the codes.
My Current code for generating bar code and qr code is as below:
Center(
child: BarcodeWidget(
data: widget.product.productId!,
barcode: Barcode.code128(),
width: 200,
height: 200,
drawText: false,
),
),
and
BarcodeWidget(
data: widget.product.productId!,
barcode: Barcode.qrCode(),
),
Both are inside a Column and I have two buttons called save and print. So how can I save and print the generated codes?
You can use RepaintBoundary
Follow these steps:
1. Create a key.
GlobalKey _screenShotKey = GlobalKey();
2. Wrap the barcode in a repaint boundary and attach the key
RepaintBoundary(
key: _screenShotKey,
child: Center(
child: BarcodeWidget(
data: widget.product.productId!,
barcode: Barcode.code128(),
width: 200,
height: 200,
drawText: false,
),
)
)
3. Import dart:ui as ui
import 'dart:ui' as ui;
4. Create a method to take a screenshot of the widget and save it.
Future<File> takeScreenshot() async {
RenderRepaintBoundary boundary =
_screenShotKey.currentContext.findRenderObject();
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 + "qr.png";
File imgFile = File(path);
return imgFile.writeAsBytes(pngBytes);
}
5. To save in gallery/photos app; Use GallerySaver package
void save() async {
takeScreenshot().then((value) async {
bool saved = await GallerySaver.saveImage(value.path);
print(saved);
}).catchError((onError) {});
}
I want to implement twitter share in my flutter application.
I convert my widget to image by using RepaintBoundary and stored as ByteData as below.
Future<ByteData> convertWidgetToImage(GlobalKey key) async {
final RenderRepaintBoundary boundary =
key.currentContext!.findRenderObject() as RenderRepaintBoundary;
final image = await boundary.toImage();
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
return byteData!;
}
Then, I want to open twitter app with some default text and with this image data. (I can convert this bytedata to local file path url if needed as below)
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Is there any way I can share this image to twitter (onTap then open twitter app with this image)?
This could be an option but I don't think I can share twitter image
https://pub.dev/packages/social_share
I have this code which loads a ui.Image using an async function:
Future<ui.Image> _loadImage() async {
final imageData = await rootBundle.load('assets/some_image.jpg');
var imageBytes = imageData.buffer.asUint8List();
return await decodeImageFromList(imageBytes);
}
But I would like to base it on AssetImage instead as it loads the correct asset version for the device pixel density. Or make it resolution aware by some other means.
There is the way to save the widget into transparent png and save it into gallery?
Thanks in advance.
Flutter draws every single pixel, so you can easily convert your widget to an image.
You need to follow these steps:
Edit -- first import path_provider link to pupspec.yaml and then follow this steps
Create a GlobalKey
final _globalKey = GlobalKey();
Create Uint8List
Uint8List pngBytes;
Wrap your widget with RepaintBoundary widget & pass in the key
RepaintBoundary(
key: _globalKey,
child: YourWidget(),
),
Create a method to convert your widget to image:
Future<void> _capturePng() async {
try {
final RenderRepaintBoundary boundary =
_globalKey.currentContext.findRenderObject();
final image = await boundary.toImage(pixelRatio: 2.0); // image quality
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
pngBytes = byteData.buffer.asUint8List();
} catch (e) {
print(e);
}
}
Convert your image to a file so that you can save it in your app
Future<File> convertImageToFile(Uint8List image) async {
final file = File(
'${(await
getTemporaryDirectory()).path}/${DateTime.now().millisecondsSinceEpoch}.png');
await file.writeAsBytes(image);
return file;
}
I'm making an app that takes a screenshot of the entire screen when clicking a button. Apparently the image goes to:
/storage/emulated/0/Android/data/com.example.program-name/files
I have tested this using the android emulator as well as my physical device. The path name changes slightly, but I still have no access to this image.
I am using the following code in order to take the screenshot and save it:
takeScreenShot() async{
RenderRepaintBoundary boundary = globalKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage();
final directory = (await getExternalStorageDirectory()).path;
print(directory);
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData.buffer.asUint8List();
File imgFile = new File('$directory/screenshot.png');
print (imgFile.toString());
imgFile.writeAsBytes(pngBytes);
}
Is there anyway to:
Access this file and move it elsewhere on the computer/phone or,
Change the following directory to one that goes to any file on your computer?
final directory = (await getExternalStorageDirectory()).path;
The idea would be to save user data on a form and save an image of the page that was just filled in for future reference. i.e. submit form, save screenshot-image to PC desktop gallery, for example.
There are issues on this. #48208 #35783
On Android you can write path by yourself.
Future<void> _screenshot() async {
RenderRepaintBoundary boundary = globalKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage();
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData.buffer.asUint8List();
Directory d = Directory('/storage/emulated/0');
if (d.existsSync()) {
Directory(d.path + '/MyApp').createSync();
File imgFile = new File(d.path + '/MyApp/screenshot.png');
print('saving to ${imgFile.path}');
imgFile.createSync();
imgFile.writeAsBytes(pngBytes);
}
}