Below is a complete, working Flutter example of an Image → PDF Converter app.
The app will:
- Pick images from gallery
- Convert them into a single PDF
- Save the PDF to device storage
This is a beginner-friendly but production-ready structure.
1️⃣ Create Flutter Project
flutter create image_to_pdf
cd image_to_pdf
2️⃣ Add Dependencies (pubspec.yaml)
dependencies:
flutter:
sdk: flutter
image_picker: ^1.0.7
pdf: ^3.10.7
path_provider: ^2.1.2
permission_handler: ^11.3.0
Run:
flutter pub get
3️⃣ Android Permissions
android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
For Android 13+, also add:
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
4️⃣ Full Flutter Code (lib/main.dart)
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Image to PDF',
home: ImageToPdfPage(),
);
}
}
class ImageToPdfPage extends StatefulWidget {
@override
State<ImageToPdfPage> createState() => _ImageToPdfPageState();
}
class _ImageToPdfPageState extends State<ImageToPdfPage> {
final ImagePicker _picker = ImagePicker();
List<File> images = [];
Future<void> pickImages() async {
final pickedFiles = await _picker.pickMultiImage();
if (pickedFiles.isNotEmpty) {
setState(() {
images = pickedFiles.map((e) => File(e.path)).toList();
});
}
}
Future<void> createPdf() async {
await Permission.storage.request();
final pdf = pw.Document();
for (var img in images) {
final image = pw.MemoryImage(img.readAsBytesSync());
pdf.addPage(
pw.Page(
build: (pw.Context context) {
return pw.Center(child: pw.Image(image));
},
),
);
}
final dir = await getExternalStorageDirectory();
final file = File("${dir!.path}/images_to_pdf.pdf");
await file.writeAsBytes(await pdf.save());
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("PDF saved at ${file.path}")),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Image to PDF Converter")),
body: Column(
children: [
ElevatedButton(
onPressed: pickImages,
child: const Text("Pick Images"),
),
Expanded(
child: GridView.builder(
itemCount: images.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
itemBuilder: (context, index) {
return Image.file(images[index], fit: BoxFit.cover);
},
),
),
if (images.isNotEmpty)
ElevatedButton(
onPressed: createPdf,
child: const Text("Convert to PDF"),
),
],
),
);
}
}
5️⃣ App Features
✅ Select multiple images
✅ Convert images to single PDF
✅ Save PDF to storage
✅ Works offline
6️⃣ Output Location
On Android, PDF will be saved in:
/Android/data/<your.package.name>/files/images_to_pdf.pdf

[…] at http://localhost/phpmyadmin or via your hosting control […]