implemented making a pdf from DetailPage.dart and croping image to 1:1 format
This commit is contained in:
+26
-1
@@ -1,8 +1,10 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'dart:math';
|
||||||
import 'package:firebase_storage/firebase_storage.dart';
|
import 'package:firebase_storage/firebase_storage.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||||
|
import 'package:image/image.dart' as img;
|
||||||
|
|
||||||
|
|
||||||
class AddScreen extends StatefulWidget {
|
class AddScreen extends StatefulWidget {
|
||||||
@@ -35,6 +37,27 @@ class _AddScreenState extends State<AddScreen> {
|
|||||||
return fileSize <= maxSizeInBytes;
|
return fileSize <= maxSizeInBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<File> _cropImage(File imageFile) async {
|
||||||
|
final originalImage = img.decodeImage(await imageFile.readAsBytes());
|
||||||
|
|
||||||
|
if (originalImage != null) {
|
||||||
|
int originSize = min(originalImage.width, originalImage.height);
|
||||||
|
final croppedImage = img.copyCrop(
|
||||||
|
originalImage,
|
||||||
|
x: (originalImage.width - originSize)~/2,
|
||||||
|
y: (originalImage.height - originSize)~/2,
|
||||||
|
width: originSize,
|
||||||
|
height: originSize
|
||||||
|
);
|
||||||
|
final newPath = imageFile.path.substring(0, imageFile.path.lastIndexOf('/'));
|
||||||
|
final newFile = File('$newPath/cropped.jpg');
|
||||||
|
await newFile.writeAsBytes(img.encodePng(croppedImage));
|
||||||
|
return newFile;
|
||||||
|
} else {
|
||||||
|
throw Exception('Unable to decode image file.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _getImage(ImageSource source) async {
|
Future<void> _getImage(ImageSource source) async {
|
||||||
final pickedFile = await ImagePicker().pickImage(source: source);
|
final pickedFile = await ImagePicker().pickImage(source: source);
|
||||||
|
|
||||||
@@ -42,8 +65,9 @@ class _AddScreenState extends State<AddScreen> {
|
|||||||
final tempFile = File(pickedFile.path);
|
final tempFile = File(pickedFile.path);
|
||||||
final bool isValid = await isFileSizeValid(tempFile, 10);
|
final bool isValid = await isFileSizeValid(tempFile, 10);
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
|
File croppedFile = await _cropImage(tempFile); // Bild zuschneiden
|
||||||
setState(() {
|
setState(() {
|
||||||
_imageFile = tempFile;
|
_imageFile = croppedFile;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
@@ -53,6 +77,7 @@ class _AddScreenState extends State<AddScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<void> addNewElementToFirestore(String title, String description, File imageFile, {required Function(bool) onComplete}) async {
|
Future<void> addNewElementToFirestore(String title, String description, File imageFile, {required Function(bool) onComplete}) async {
|
||||||
String collectionName;
|
String collectionName;
|
||||||
if (_selectedIndex == 0) {
|
if (_selectedIndex == 0) {
|
||||||
|
|||||||
+56
-1
@@ -1,5 +1,9 @@
|
|||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'dart:typed_data';
|
||||||
|
import 'package:pdf/widgets.dart' as pdfWidgets;
|
||||||
|
import 'package:printing/printing.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
|
||||||
class DetailPage extends StatelessWidget {
|
class DetailPage extends StatelessWidget {
|
||||||
final String title;
|
final String title;
|
||||||
@@ -15,11 +19,62 @@ class DetailPage extends StatelessWidget {
|
|||||||
required this.imageUrl,
|
required this.imageUrl,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> _printPdf() async {
|
||||||
|
final pdf = pdfWidgets.Document();
|
||||||
|
final image = await _loadNetworkImage(imageUrl);
|
||||||
|
|
||||||
|
pdf.addPage(
|
||||||
|
pdfWidgets.MultiPage(
|
||||||
|
build: (context) => [
|
||||||
|
pdfWidgets.Center(
|
||||||
|
child: pdfWidgets.SizedBox(
|
||||||
|
width: double.infinity, // Die Breite auf die maximal mögliche Breite setzen
|
||||||
|
child: pdfWidgets.AspectRatio(
|
||||||
|
aspectRatio: 1, // Sie können das Seitenverhältnis entsprechend Ihrem Bild anpassen
|
||||||
|
child: pdfWidgets.Image(image),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pdfWidgets.Text(
|
||||||
|
title,
|
||||||
|
style: pdfWidgets.TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: pdfWidgets.FontWeight.bold // Titel fett
|
||||||
|
)
|
||||||
|
),
|
||||||
|
pdfWidgets.Text(datum, style: const pdfWidgets.TextStyle(fontSize: 14, )),
|
||||||
|
pdfWidgets.Paragraph(text: description, style: const pdfWidgets.TextStyle(fontSize: 12)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await Printing.sharePdf(bytes: await pdf.save(), filename: '$title.pdf');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<pdfWidgets.ImageProvider> _loadNetworkImage(String url) async {
|
||||||
|
final response = await http.get(Uri.parse(url));
|
||||||
|
|
||||||
|
if (response.statusCode != 200) {
|
||||||
|
throw Exception('Failed to load network image.');
|
||||||
|
}
|
||||||
|
|
||||||
|
final Uint8List bytes = response.bodyBytes;
|
||||||
|
final imageProvider = pdfWidgets.MemoryImage(bytes);
|
||||||
|
|
||||||
|
return imageProvider;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(title),
|
title: Text(title),
|
||||||
|
actions: <Widget>[
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.picture_as_pdf),
|
||||||
|
onPressed: _printPdf,
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
body: SingleChildScrollView(
|
body: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|||||||
+81
-1
@@ -25,6 +25,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.10.0"
|
version: "2.10.0"
|
||||||
|
barcode:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: barcode
|
||||||
|
sha256: "52570564684bbb0240a9f1fdb6bad12adc5e0540103c1c96d6dd550bd928b1c9"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.3"
|
||||||
|
bidi:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: bidi
|
||||||
|
sha256: dc00274c7edabae2ab30c676e736ea1eb0b1b7a1b436cb5fe372e431ccb39ab0
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.6"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -312,6 +328,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.16"
|
version: "4.0.16"
|
||||||
|
image_cropper:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: image_cropper
|
||||||
|
sha256: "710ab4b7953e9ce1d27d833f741e5f8f3afb0b0ba3556dc0b844741b5f55c2b3"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.3"
|
||||||
|
image_cropper_for_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_cropper_for_web
|
||||||
|
sha256: "09e93a8ec0435adcaa23622ac090442872f18145d70b9ff605ffedcf97d56255"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.3"
|
||||||
|
image_cropper_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_cropper_platform_interface
|
||||||
|
sha256: "62349e3aab63873ea9b9ab9f69d036ab8a0d74b3004beec4303981386cb9273f"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.3"
|
||||||
image_picker:
|
image_picker:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -416,6 +456,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.2"
|
version: "1.8.2"
|
||||||
|
path_parsing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_parsing
|
||||||
|
sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
path_provider:
|
path_provider:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -464,6 +512,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.6"
|
version: "2.1.6"
|
||||||
|
pdf:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: pdf
|
||||||
|
sha256: "586d3debf5432e5377044754032cfa53ab45e9abf371d4865e9ad5019570e246"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.10.1"
|
||||||
|
pdf_widget_wrapper:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pdf_widget_wrapper
|
||||||
|
sha256: "754867bf32c4683da29ccc6bf31250905431fb0818a7258c153e21cd627b3212"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
pedantic:
|
pedantic:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -504,6 +568,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.7.3"
|
version: "3.7.3"
|
||||||
|
printing:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: printing
|
||||||
|
sha256: "6aa86779d51f1c60608defee7b231e1133ab9b00f63b3b71abfa85cb39898571"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.10.4"
|
||||||
process:
|
process:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -512,6 +584,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.4"
|
version: "4.2.4"
|
||||||
|
qr:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: qr
|
||||||
|
sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
rxdart:
|
rxdart:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -647,4 +727,4 @@ packages:
|
|||||||
version: "6.2.2"
|
version: "6.2.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.19.0 <3.0.0"
|
dart: ">=2.19.0 <3.0.0"
|
||||||
flutter: ">=3.3.0"
|
flutter: ">=3.7.0"
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ dependencies:
|
|||||||
change_app_package_name: ^1.1.0
|
change_app_package_name: ^1.1.0
|
||||||
cached_network_image: ^3.2.3
|
cached_network_image: ^3.2.3
|
||||||
image: ^4.0.16
|
image: ^4.0.16
|
||||||
|
pdf: ^3.10.1
|
||||||
|
printing: ^5.10.4
|
||||||
|
image_cropper: ^3.0.3
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user