How to share PDF files in flutter - flutter

There does not appear to be any pub.dev plugin that allows sharing of PDF files.
My app creates PDFs.. I want to be able to share these PDFs.
So far, it seems that all these plugins only support sharing of PNG's..
How should I share my PDF?

I've used package esys_flutter_share
var sharePdf = await file.readAsBytes();
await Share.file(
'PDF Document',
'project.pdf',
sharePdf.buffer.asUint8List(),
'*/*',
);

I finally achieved it by using the below package as esys_flutter_share no null safety.
path_provider: ^2.0.12
share_plus: ^6.3.1
screenshot: ^1.3.0
First creating the function==> widget to pdf
class _MyGoalDetailsState extends State<MyGoalDetails> {
List<GlobalKey> printKey = List<GlobalKey>.generate(100, (index) => GlobalKey(debugLabel: 'key_$index'),growable: false);
final doc = pw.Document();
// ========== Funtion() for widget to pdf ============
void _printScreen(int index) async {
final image = await WidgetWraper.fromKey(
key: printKey[index],
pixelRatio: 2.0,
);
final directory = await getTemporaryDirectory();
final file = File('${directory.path}/my_goal.pdf');
final pdf = pw.Document();
pdf.addPage(pw.Page(
build: (pw.Context context) {
return pw.Center(
child: pw.Image(image),
);
},
));
await file.writeAsBytes(await pdf.save());
await Share.shareFiles(
[file.path],
text: 'Check out my goal details',
subject: 'My goal details',
);
}
......................................
...................
Then wrap the widget which I want to pdf.
RepaintBoundary(
key: printKey[0],
child: Container(
color: Colors.white,
padding: const EdgeInsets.fromLTRB(15,15,15,0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [.................................
And onPress of my share button creating my pdf..
IconButton(
onPressed: () async {
_printScreen(0);
},
icon: const Icon(Icons.share),
),

Related

How to take screenshot of entire screen outside of your FLUTTER DESKTOP app(mostly for Windows OS)?

I'm new to flutter. Now I am able to take screenshot for my entire desktop app screen using Screenshot package & storing that image to local storage.
But my requirement is to capture the screenshot of entire screen of the window, like if 2 applications are opened(1 Flutter + 1 any other app e.g. browser) in 1 screen, then we can able to take whole screen's screenshot not only flutter app.
Please help me on how to take entire window's screenshot in Windows OS desktop app?
If it's not possible directly from Flutter, then how to achieve this by implementing some native code with Flutter?
check this completely working as expected
bool _isAccessAllowed = false;
CapturedData? _lastCapturedData;
#override
void initState() {
super.initState();
_init();
}
void _init() async {
_isAccessAllowed = await ScreenCapturer.instance.isAccessAllowed();
}
void _handleClickCapture(CaptureMode mode) async {
Directory directory = await getApplicationDocumentsDirectory();
String imageName =
'Screenshot-${DateTime.now().millisecondsSinceEpoch}.png';
String imagePath =
'${directory.path}/screen_capturer_example/Screenshots/$imageName';
_lastCapturedData = await ScreenCapturer.instance.capture(
mode: mode,
imagePath: imagePath,
silent: true,
);
if (_lastCapturedData != null) {
// ignore: avoid_print
// print(_lastCapturedData!.toJson());
} else {
// ignore: avoid_print
print('User canceled capture');
}
setState(() {});
}
Widget _buildBody(BuildContext context) {
return PreferenceList(
children: <Widget>[
if (Platform.isMacOS)
PreferenceListSection(
children: [
PreferenceListItem(
title: const Text('isAccessAllowed'),
accessoryView: Text('$_isAccessAllowed'),
onTap: () async {
bool allowed =
await ScreenCapturer.instance.isAccessAllowed();
BotToast.showText(text: 'allowed: $allowed');
setState(() {
_isAccessAllowed = allowed;
});
},
),
PreferenceListItem(
title: const Text('requestAccess'),
onTap: () async {
await ScreenCapturer.instance.requestAccess();
},
),
],
),
PreferenceListSection(
title: const Text('METHODS'),
children: [
PreferenceListItem(
title: const Text('capture'),
accessoryView: Row(children: [
CupertinoButton(
child: const Text('region'),
onPressed: () {
_handleClickCapture(CaptureMode.region);
},
),
CupertinoButton(
child: const Text('screen'),
onPressed: () {
_handleClickCapture(CaptureMode.screen);
},
),
CupertinoButton(
child: const Text('window'),
onPressed: () {
_handleClickCapture(CaptureMode.window);
},
),
]),
),
],
),
if (_lastCapturedData != null && _lastCapturedData?.imagePath != null)
Container(
margin: const EdgeInsets.only(top: 20),
width: 400,
height: 400,
child: Image.file(
File(_lastCapturedData!.imagePath!),
),
),
],
);
}
// screen shot taken by the App.
You might try using this package: screen_capturer. It works on Windows, Linux and MacOS.
From the docs:
Example of usage:
import 'package:screen_capturer/screen_capturer.dart';
CapturedData? capturedData = await screenCapturer.capture(
mode: CaptureMode.screen, // screen, window
imagePath: '<path>',
);
CaptureMode.screen is to capture the entire screen.
The screenshot package which you mention is only for taking screenshots for widgets of your app not of whole screen.

How to render image from Firebase without rebuilding?

I'm trying to implement profile image picking in my flutter app using Firebase Storage. I use image_picker to get the image and upload it to Firebase, get the download link and add the download link to the imgsrc field in the cloud firestore, from where I can render the NetworkImage.
Center(
child: Stack(
children: [
buildImage(),
Positioned(
bottom: 5,
right: 5,
child: GestureDetector(
onTap: showPhotoAlertDialog,
child: buildEditIcon(Color(0xff407bff))),
),
],
),
),
How can I get the default Icons.person kind image for when the user has no profile image, and get the image from the database otherwise?
The code I'm using right now is as follows:
Widget buildImage() {
return CircleAvatar(
backgroundImage: NetworkImage(loggedInUser.imgsrc ??
'https://th.bing.com/th/id/R.945f33b643f2ceffcdae90fb57c61854?rik=XcI0SYBgSefoCA&riu=http%3a%2f%2fgetdrawings.com%2ffree-icon-bw%2fanonymous-avatar-icon-19.png&ehk=5n%2buJG66CeLQZsmhaMt8gag5rXuM3TdebAL6W35K1E4%3d&risl=&pid=ImgRaw&r=0'),
backgroundColor: Colors.grey[350],
radius: 100,
);
}
I created an Alert Dialog widget to choose whether to choose the image from camera or from the gallery.
showPhotoAlertDialog() {
AlertDialog alert = AlertDialog(
title: Text("Upload from"),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
onPressed: () {
imageFromCamera()
.then((value) => uploadFile())
.whenComplete(() => postSource());
setState(() {}); ----->
},
child: Text("Upload from camera"),
),
TextButton(
onPressed: () {
imageFromGallery().then((value) => uploadFile());
postSource();
setState(() {});
},
child: Text("Upload from gallery"),
)
],
),
);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
To upload the image to storage and post the source to cloud firestore, I use the following methods:
Future uploadFile() async {
if (file == null) return;
final fileName = path.basename(file!.path);
final destination = 'files/$fileName';
task = FirebaseApi.uploadFile(destination, file!);
setState(() {});
if (task == null) return;
final snapshot = await task!.whenComplete(() {});
urlDownload = await snapshot.ref.getDownloadURL();
print('Download-Link: $urlDownload');
}
postSource() async {
FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
await firebaseFirestore
.collection("users")
.doc(user?.uid)
.update({'imgsrc': urlDownload});
}
The link gets uploaded properly and I'm able to get the link in my NetworkImage, but it doesn't get rendered immediately. I have to close the parent drawer and open it again to get it. I call setState(){} as well after posting the source, but it doesn't make any difference. How can I get the image without having to close and open the drawer?
Any help would be appreciated!
Thanks
You also have to update image in model class or in this imgsrc also just add this line above setState in onPressed of TextButton.
loggedInUser.imgsrc = urlDownload;

Failed to run model, -67108857, java.lang.NegativeArrayS izeException: -67108857

Has anyone solved this problem while using tflite package in flutter every model i used i get that issue of arrays?
Unhandled Exception: PlatformException(Failed to run model, -67108857, java.lang.NegativeArrayS
izeException: -67108857
How can i solve it.
Here is the basic code i was trying to run but landed into an error.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:tflite/tflite.dart';
import 'package:image_picker/image_picker.dart';
import 'home.dart';
//import 'package:image/image.dart' as img;
void main() => runApp(MyApp());
const String ssd = "SSD MobileNet";
const String yolo = "Tiny YOLOv2";
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Object Detection App',
home: StaticImage(),
);
}
}
class StaticImage extends StatefulWidget {
#override
_StaticImageState createState() => _StaticImageState();
}
class _StaticImageState extends State<StaticImage> {
File _image;
List _recognitions;
bool _busy;
double _imageWidth, _imageHeight;
final picker = ImagePicker();
// this function loads the model
loadTfModel() async {
await Tflite.loadModel(
model: "assets/tflite/model_unquant.tflite",
labels: "assets/tflite/label.txt",
);
}
// this function detects the objects on the image
detectObject(File image) async {
var recognitions = await Tflite.detectObjectOnImage(
path: image.path, // required
model: "SSDMobileNet",
imageMean: 127.5,
imageStd: 127.5,
threshold: 0.4, // defaults to 0.1
numResultsPerClass: 10,// defaults to 5
asynch: true // defaults to true
);
FileImage(image)
.resolve(ImageConfiguration())
.addListener((ImageStreamListener((ImageInfo info, bool _) {
setState(() {
_imageWidth = info.image.width.toDouble();
_imageHeight = info.image.height.toDouble();
});
})));
setState(() {
_recognitions = recognitions;
});
}
#override
void initState() {
super.initState();
_busy = true;
loadTfModel().then((val) {{
setState(() {
_busy = false;
});
}});
}
// display the bounding boxes over the detected objects
List<Widget> renderBoxes(Size screen) {
if (_recognitions == null) return [];
if (_imageWidth == null || _imageHeight == null) return [];
double factorX = screen.width;
double factorY = _imageHeight / _imageHeight * screen.width;
Color blue = Colors.blue;
return _recognitions.map((re) {
return Container(
child: Positioned(
left: re["rect"]["x"] * factorX,
top: re["rect"]["y"] * factorY,
width: re["rect"]["w"] * factorX,
height: re["rect"]["h"] * factorY,
child: ((re["confidenceInClass"] > 0.50))? Container(
decoration: BoxDecoration(
border: Border.all(
color: blue,
width: 3,
)
),
child: Text(
"${re["detectedClass"]} ${(re["confidenceInClass"] * 100).toStringAsFixed(0)}%",
style: TextStyle(
background: Paint()..color = blue,
color: Colors.white,
fontSize: 15,
),
),
) : Container()
),
);
}).toList();
}
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
List<Widget> stackChildren = [];
stackChildren.add(
Positioned(
// using ternary operator
child: _image == null ?
Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Please Select an Image"),
],
),
)
: // if not null then
Container(
child:Image.file(_image)
),
)
);
stackChildren.addAll(renderBoxes(size));
if (_busy) {
stackChildren.add(
Center(
child: CircularProgressIndicator(),
)
);
}
return Scaffold(
appBar: AppBar(
title: Text("Object Detector"),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
heroTag: "Fltbtn2",
child: Icon(Icons.camera_alt),
onPressed: getImageFromCamera,
),
SizedBox(width: 10,),
FloatingActionButton(
heroTag: "Fltbtn1",
child: Icon(Icons.photo),
onPressed: getImageFromGallery,
),
],
),
body: Container(
alignment: Alignment.center,
child:Stack(
children: stackChildren,
),
),
);
}
// gets image from camera and runs detectObject
Future getImageFromCamera() async {
final pickedFile = await picker.getImage(source: ImageSource.camera);
setState(() {
if(pickedFile != null) {
_image = File(pickedFile.path);
} else {
print("No image Selected");
}
});
detectObject(_image);
}
// gets image from gallery and runs detectObject
Future getImageFromGallery() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
if(pickedFile != null) {
_image = File(pickedFile.path);
} else {
print("No image Selected");
}
});
detectObject(_image);
}
}
This is the code i was trying to run
Image for error is here
name: ml_classifier
description: A new Flutter project.
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
tflite: ^1.0.4
image_picker: ^0.6.1+8
image: ^2.1.4
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
dev_dependencies:
flutter_test:
sdk: flutter
# The following section is specific to Flutter.
flutter:
# To add assets to your application, add an assets section, like this:
assets:
- assets/tflite/model_unquant.tflite
- assets/tflite/label.txt

how to pick multiple images from gallery and store them in array in flutter?

i used image_picker package in my app and it works fine for one image but now i want to use it for multiple images and store them in an array as File. any idea could be greate.
Add dependecy of image_picker:
image_picker: ^0.8.4+3
Then make a method for selectImages():
final ImagePicker imagePicker = ImagePicker();
List<XFile>? imageFileList = [];
void selectImages() async {
final List<XFile>? selectedImages = await
imagePicker.pickMultiImage();
if (selectedImages!.isNotEmpty) {
imageFileList!.addAll(selectedImages);
}
print("Image List Length:" + imageFileList!.length.toString());
setState((){});
}
Create a builder for showing selected Images:
return Scaffold(
appBar: AppBar(
title: Text('Multiple Images'),
),
body: SafeArea(
child: Column(
children: [
ElevatedButton(
onPressed: () {
selectImages();
},
child: Text('Select Images'),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: GridView.builder(
itemCount: imageFileList!.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemBuilder: (BuildContext context, int index) {
return Image.file(File(imageFileList![index].path),
fit: BoxFit.cover,);
}),
),
),
],
),
));
Complete Source code available in github link...
https://github.com/NishaJain24/multi_image_picker
you should use this
//add this to pubspec.yaml
multi_image_picker: ^4.7.14
//add those to the dart file
import 'package:flutter/material.dart';
import 'package:multi_image_picker/multi_image_picker.dart';
import 'dart:async';
//add a button then in onPressed do this
MultiImagePicker.pickImages(
maxImages: 300,
enableCamera: true,
selectedAssets: images,
materialOptions: MaterialOptions(
actionBarTitle: "FlutterCorner.com",
),
);
for further infos check this
https://medium.com/#fluttercorner/how-to-select-multiple-images-with-flutter-8fe8e4c78d08
The documentation covers that in here .
final List<XFile>? images = await _picker.pickMultiImage(source: ImageSource.gallery);
That saves it in a list of XFile. There are some platform specific implementation you have to go through so dont miss that. Just have a look at the documentation.

How to add photos to a PDF in flutter

I use this library https://pub.dev/packages/pdf to generate a PDF. The problem is that I can’t manage to add photos to my PDF. The path for each photo is saved in a List of objects. This is how I try to approach the implementation:
import 'package:pdf/widgets.dart' as pw;
​
​
Future<void> generatePDF() async {
​
pdf = pw.Document();
​
pdf.addPage(
pw.MultiPage(
pageFormat: PdfPageFormat.a4,
build: (pw.Context context) => [
pw.Partitions(
children: [
pw.Partition(
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: <pw.Widget>[
​
/// Photos list
pw.ListView.builder(
itemCount: 1,
itemBuilder: (pw.Context context, int index) {
return pw.Column(
children: _photosList
?.map(
(photo) async => pw.Column(
children: <pw.Widget>[
pw.Text(
"Photo id: ${photo.photoId} - Photo type: ${photo.photoType}"), // This is displayed correctly for each photo
pw.Image(
pw.MemoryImage(
(await rootBundle
.load('${photo.photoPath}')) // This is not working because the photos are not in rootBundle and I can't find a solution to replace this line
.buffer
.asUint8List(),
),
),
],
),
)
?.toList() ??
[],
);
},
),
],
),
),
],
),
],
),
);
print('PDF Generated');
}
Output:
Import dart:io
import 'dart:io';
If you have a path, you can make a File out of it.
File photo1 = File(photo.photoPath);
Then, you can load in that File to the PDF by using the following statements:
MemoryImage memoryImage = pw.MemoryImage(photo1.readAsBytesSync()); //you could use async as well
This leaves you with a MemoryImage from you photoPath. Then you can simply add it:
pw.Image(memoryImage)