flutter_pdf_annotations 1.3.0
flutter_pdf_annotations: ^1.3.0 copied to clipboard
A Flutter plugin for annotating PDFs natively on iOS and Android. Supports drawing, highlighting, image stamping, and saving.
flutter_pdf_annotations #
A Flutter plugin for opening and annotating PDF files natively on iOS and Android.
Presents a full-screen native editor with freehand drawing, highlighting, image stamping, erasing, undo, color picker, and pen-size presets β then saves the annotated PDF back to a file path of your choice.
Features #
| Feature | Description |
|---|---|
| Freehand pen | Draw with custom colour and stroke width |
| Highlighter | Semi-transparent highlight with adjustable opacity |
| Image stamps | Place signatures, logos, or images β resize, accept, or delete |
| Eraser | Remove individual annotations |
| Undo | Step back through all annotation types |
| Save | Write the annotated PDF to any writable path |
| Share | Share via the native share sheet |
| Multiple sources | Open from file path, raw bytes, URL, or Flutter asset |
| Typed results | Distinguish success, cancellation, and errors without try/catch |
| Localization | Native UI in English π¬π§, Arabic πΈπ¦, Spanish πͺπΈ, and Portuguese π΅πΉ |
Platform Support #
| Android | iOS |
|---|---|
| API 21+ | iOS 14+ |
Getting Started #
1. Install #
dependencies:
flutter_pdf_annotations: ^1.3.0
flutter pub get
2. Platform Setup #
Android
No extra permissions or setup needed for paths inside the app's own directories (getExternalFilesDir, filesDir).
If you plan to download PDFs from the internet using openFromUrl, make sure your AndroidManifest.xml includes:
<uses-permission android:name="android.permission.INTERNET"/>
iOS
If you allow the user to pick images for stamping, add to ios/Runner/Info.plist:
<key>NSPhotoLibraryUsageDescription</key>
<string>Select images to insert into PDF annotations</string>
Usage #
Open a local PDF #
import 'package:flutter_pdf_annotations/flutter_pdf_annotations.dart';
final result = await FlutterPdfAnnotations.openPDF(
filePath: '/path/to/document.pdf',
);
if (result.isSuccess) {
print('Saved to: ${result.savedPath}');
} else if (result.isCancelled) {
print('User cancelled');
} else {
print('Error: ${result.error}');
}
With configuration #
final result = await FlutterPdfAnnotations.openPDF(
filePath: '/path/to/document.pdf',
savePath: '/path/to/annotated.pdf',
config: PDFAnnotationConfig(
title: 'Review Contract',
initialPenColor: Colors.red,
initialHighlightColor: Colors.yellow.withOpacity(0.5),
initialStrokeWidth: 3.0,
initialPage: 2, // open at page 3 (zero-based)
locale: PdfLocale.arabic, // force Arabic UI
),
);
With image stamps #
final signatureBytes = await File('signature.png').readAsBytes();
final result = await FlutterPdfAnnotations.openPDF(
filePath: '/path/to/document.pdf',
config: PDFAnnotationConfig(
title: 'Sign Document',
imagesToInsert: [signatureBytes],
),
);
From a URL (with optional headers) #
final result = await FlutterPdfAnnotations.openFromUrl(
url: 'https://example.com/document.pdf',
headers: {
'Authorization': 'Bearer your_token',
'X-Custom-Header': 'value',
},
config: PDFAnnotationConfig(title: 'Remote PDF'),
);
From raw bytes #
final Uint8List pdfBytes = /* from network, database, etc. */;
final result = await FlutterPdfAnnotations.openFromBytes(
bytes: pdfBytes,
config: PDFAnnotationConfig(title: 'In-Memory PDF'),
);
From a Flutter asset #
// Declare in pubspec.yaml:
// flutter:
// assets:
// - assets/sample.pdf
final result = await FlutterPdfAnnotations.openFromAsset(
assetPath: 'assets/sample.pdf',
);
Localization #
The native editor UI is automatically displayed in the device language. You can also force a specific language via PDFAnnotationConfig.locale.
| Enum | Language | Flag |
|---|---|---|
PdfLocale.english |
English (default fallback) | π¬π§ |
PdfLocale.arabic |
Arabic | πΈπ¦ |
PdfLocale.spanish |
Spanish | πͺπΈ |
PdfLocale.portuguese |
Portuguese | π΅πΉ |
// Auto-detect from device (recommended)
PDFAnnotationConfig()
// Force a specific language
PDFAnnotationConfig(locale: PdfLocale.arabic)
PDFAnnotationConfig(locale: PdfLocale.spanish)
PDFAnnotationConfig(locale: PdfLocale.portuguese)
Any unsupported device locale falls back to English automatically.
API Reference #
FlutterPdfAnnotations #
| Method | Description |
|---|---|
openPDF({filePath, savePath?, config?}) |
Open a PDF from a local file path |
openFromBytes({bytes, savePath?, config?}) |
Open a PDF from Uint8List bytes |
openFromUrl({url, headers?, savePath?, config?}) |
Download and open a PDF from a URL |
openFromAsset({assetPath, savePath?, config?}) |
Open a PDF bundled as a Flutter asset |
All methods return Future<PdfAnnotationResult>.
PdfAnnotationResult #
| Property | Type | Description |
|---|---|---|
isSuccess |
bool |
true when the user saved β savedPath is non-null |
savedPath |
String? |
Output file path |
isCancelled |
bool |
true when the user dismissed without saving |
isError |
bool |
true when an error occurred |
error |
String? |
Error description |
PDFAnnotationConfig #
| Parameter | Type | Default | Description |
|---|---|---|---|
title |
String? |
'PDF Annotations' |
Editor navigation bar title |
initialPenColor |
Color? |
Red | Starting pen colour |
initialHighlightColor |
Color? |
Yellow (50% opacity) | Starting highlight colour (include alpha) |
initialStrokeWidth |
double? |
8.0 (M) |
Starting stroke width β 3.0 (S), 8.0 (M), 18.0 (L) |
imagesToInsert |
List<Uint8List>? |
null |
Images available for stamping (PNG, JPEG, etc.) |
initialPage |
int |
0 |
Zero-based page index to open at |
locale |
PdfLocale? |
device locale | Editor UI language β see Localization |
PdfLocale #
enum PdfLocale { english, arabic, spanish, portuguese }
Contributing #
Pull requests are welcome. Please open an issue first to discuss the change.
License #
MIT Β© 2025-2026 Mohamed Ghoneim