pdf_to_image_converter
A Flutter package that provides easy-to-use utilities for converting PDF documents to images. Perfect for apps that need to display, edit, or share PDF content as images.
Features
- PDF File Selection - Built-in file picker for easy PDF selection
- Page-by-Page Rendering - Convert individual PDF pages to high-quality images
- Quality Presets - 6 predefined quality levels (thumbnail, low, medium, high, print, ultra)
- Page Rotation - Render pages at 0°, 90°, 180°, or 270° angles
- Batch Processing - Render and save all pages at once with progress tracking
- Page Range Rendering - Convert specific page ranges (e.g., pages 5-10)
- Thumbnail Generation - Quick low-resolution previews with custom dimensions
- Custom Per-Page Settings - Different quality/rotation for each page in batch operations
- Cancellation Support - Stop long-running operations mid-process
- Page Dimensions - Get size and dimensions for single or all pages
- PDF Metadata - Extract document info (title, page count, etc.)
- File Export - Save rendered images to files with custom paths and naming
- High Performance - Optimized rendering with customizable scale
- Progress Callbacks - Track rendering and saving progress in real-time
- Fully Documented - 100% dartdoc coverage for all public APIs
Installation
- Add the latest version of package to your pubspec.yaml (and run
dart pub get):
dependencies:
pdf_to_image_converter: ^0.0.4
- Import the package and use it in your Flutter App.
import 'package:pdf_to_image_converter/pdf_to_image_converter.dart';
Example
The pdf_to_image_converter package allows you to select a PDF file, render its pages as images, and save them to the gallery.
|
Quick Start
Here's a minimal example to get you started:
import 'dart:io';
import 'package:pdf_to_image_converter/pdf_to_image_converter.dart';
import 'package:path_provider/path_provider.dart';
// Pick a PDF file
final path = await PdfPicker.pickPdf();
if (path != null) {
// Create converter instance
final converter = PdfImageConverter();
// Open the PDF
await converter.openPdf(path);
// Get PDF metadata
print('Total pages: ${converter.pageCount}');
print('Title: ${converter.metadata?.title}');
// Get page dimensions
final size = await converter.getPageSize(0);
print('Page size: ${size?.width} x ${size?.height}');
// Render with quality preset
final imageBytes = await converter.renderPage(
0,
quality: RenderQuality.high,
);
// Get directory to save image
final directory = await getApplicationDocumentsDirectory();
final filePath = '${directory.path}/page_1.png';
// Save to file
await converter.saveImage(imageBytes, filePath, (success) {
print('Saved: $success');
});
// Clean up
await converter.closePdf();
}
Batch Processing with Cancellation
Convert all pages at once with progress tracking and cancellation support:
import 'dart:io';
import 'package:path_provider/path_provider.dart';
final path = await PdfPicker.pickPdf();
if (path != null) {
final converter = PdfImageConverter();
await converter.openPdf(path);
// Create cancellation token
final token = CancellationToken();
// Render all pages with progress and quality preset
final images = await converter.renderAllPages(
quality: RenderQuality.medium,
cancellationToken: token,
onProgress: (current, total) {
print('Rendering: $current/$total');
// Cancel after 5 pages if needed
// if (current >= 5) token.cancel();
},
);
// Get output directory
final directory = await getApplicationDocumentsDirectory();
final outputDir = '${directory.path}/pdf_images';
// Save all images with progress
final saved = await converter.saveAllImages(
images,
outputDir,
fileNamePattern: 'page_{index}.png',
cancellationToken: token,
onProgress: (current, total, success) {
print('Saving: $current/$total - Success: $success');
},
);
print('Saved $saved images to $outputDir');
await converter.closePdf();
}
Usage Examples
1. Using Quality Presets
Quality presets provide optimized settings for different use cases:
// Thumbnail quality (1.0x) - Fast, low quality
final thumbnail = await converter.renderPage(0, quality: RenderQuality.thumbnail);
// Low quality (1.5x) - Quick previews
final preview = await converter.renderPage(0, quality: RenderQuality.low);
// Medium quality (2.0x) - Balanced
final medium = await converter.renderPage(0, quality: RenderQuality.medium);
// High quality (3.0x) - Default, best for viewing
final high = await converter.renderPage(0, quality: RenderQuality.high);
// Print quality (4.0x) - High resolution
final print = await converter.renderPage(0, quality: RenderQuality.print);
// Ultra quality (5.0x) - Maximum quality
final ultra = await converter.renderPage(0, quality: RenderQuality.ultra);
2. Page Rotation
Rotate pages while rendering:
// Normal orientation
final normal = await converter.renderPage(0, rotation: PageRotation.rotate0);
// Rotate 90 degrees clockwise
final rotated90 = await converter.renderPage(0, rotation: PageRotation.rotate90);
// Rotate 180 degrees
final rotated180 = await converter.renderPage(0, rotation: PageRotation.rotate180);
// Rotate 270 degrees clockwise (90 counter-clockwise)
final rotated270 = await converter.renderPage(0, rotation: PageRotation.rotate270);
3. Page Range Rendering
Convert only specific pages:
// Render pages 5-10 (indices 4-9)
final images = await converter.renderPageRange(
startPage: 4,
endPage: 9,
quality: RenderQuality.medium,
onProgress: (current, total) {
print('Progress: $current/$total');
},
);
4. Thumbnail Generation
Quick low-resolution previews:
// Single thumbnail
final thumbnail = await converter.renderThumbnail(
0,
maxWidth: 200,
maxHeight: 300,
);
// All thumbnails
final thumbnails = await converter.renderAllThumbnails(
maxWidth: 150,
maxHeight: 200,
onProgress: (current, total) {
print('Generated $current/$total thumbnails');
},
);
5. Custom Settings Per Page
Apply different settings to different pages:
final images = await converter.renderPagesWithConfig([
PageRenderConfig(
pageIndex: 0,
scale: 2.0,
background: Colors.white,
),
PageRenderConfig(
pageIndex: 1,
scale: 3.0,
rotation: PageRotation.rotate90,
),
PageRenderConfig(
pageIndex: 2,
scale: 1.5,
background: Colors.grey[200]!,
),
]);
6. Cancellation Support
Stop long operations:
final token = CancellationToken();
// Start rendering in background
Future.delayed(Duration.zero, () async {
final images = await converter.renderAllPages(
quality: RenderQuality.high,
cancellationToken: token,
onProgress: (current, total) {
print('Rendering: $current/$total');
},
);
print('Completed: ${images.length} pages');
});
// Cancel after 3 seconds
await Future.delayed(Duration(seconds: 3));
token.cancel();
print('Cancelled!');
7. Getting All Page Sizes
Analyze page dimensions before rendering:
final sizes = await converter.getAllPageSizes();
for (int i = 0; i < sizes.length; i++) {
print('Page $i: ${sizes[i].width} x ${sizes[i].height}');
}
8. Accessing PDF Metadata
Get document information:
await converter.openPdf(path);
final metadata = converter.metadata;
print('Page count: ${metadata?.pageCount}');
print('Title: ${metadata?.title}');
API Documentation
PdfImageConverter
Main class for handling PDF to image conversion.
Properties
bool isOpen- Returns true if a PDF is currently openint pageCount- Total number of pages in the open PDFint currentPage- Index of the currently rendered pagePdfMetadata? metadata- Metadata of the currently open PDF
Core Methods
Future<void> openPdf(String path)- Opens a PDF from file pathFuture<void> closePdf()- Closes the PDF and releases resources
Rendering Methods
Future<Uint8List?> renderPage(int pageIndex, {double? scale, RenderQuality quality, Color background, PageRotation rotation})- Renders a single page with customizable settingsFuture<List<Uint8List?>> renderAllPages({double? scale, RenderQuality quality, Color background, PageRotation rotation, CancellationToken? cancellationToken, Function? onProgress})- Renders all pages with optional cancellationFuture<List<Uint8List?>> renderPageRange({required int startPage, required int endPage, double? scale, RenderQuality quality, Color background, PageRotation rotation, CancellationToken? cancellationToken, Function? onProgress})- Renders a specific range of pagesFuture<Uint8List?> renderThumbnail(int pageIndex, {double maxWidth, double maxHeight, Color background})- Generates a thumbnail with max dimensionsFuture<List<Uint8List?>> renderAllThumbnails({double maxWidth, double maxHeight, Color background, CancellationToken? cancellationToken, Function? onProgress})- Generates thumbnails for all pagesFuture<List<Uint8List?>> renderPagesWithConfig(List<PageRenderConfig> pageConfigs, {CancellationToken? cancellationToken, Function? onProgress})- Renders multiple pages with custom settings per page
Page Information Methods
Future<Size?> getPageSize(int pageIndex)- Gets the dimensions of a specific pageFuture<List<Size>> getAllPageSizes()- Gets dimensions of all pages
Saving Methods
Future<void> saveImage(Uint8List imageBytes, String filePath, Function(bool) onSave)- Saves a single image to fileFuture<int> saveAllImages(List<Uint8List?> imagesList, String outputDirectory, {String fileNamePattern, CancellationToken? cancellationToken, Function? onProgress})- Saves multiple images with custom naming
RenderQuality Enum
Predefined quality presets:
RenderQuality.thumbnail- 1.0x scaleRenderQuality.low- 1.5x scaleRenderQuality.medium- 2.0x scaleRenderQuality.high- 3.0x scale (default)RenderQuality.print- 4.0x scaleRenderQuality.ultra- 5.0x scale
PageRotation Enum
Rotation angles:
PageRotation.rotate0- No rotation (0°)PageRotation.rotate90- 90° clockwisePageRotation.rotate180- 180° rotationPageRotation.rotate270- 270° clockwise (90° counter-clockwise)
PageRenderConfig Class
Configuration for rendering individual pages:
PageRenderConfig({
required int pageIndex,
double scale = 3.0,
Color background = Colors.white,
PageRotation rotation = PageRotation.rotate0,
})
CancellationToken Class
Token for cancelling operations:
bool isCancelled- Check if cancellation was requestedvoid cancel()- Request cancellationvoid reset()- Reset the token state
PdfMetadata Class
Contains PDF document metadata:
int pageCount- Total number of pagesString? title- Document titleString? author- Document authorString? subject- Document subjectString? creator- Creating applicationString? producer- PDF producerDateTime? creationDate- Creation dateDateTime? modificationDate- Last modification date
PdfPicker
Utility class for PDF file selection.
Methods
static Future<String?> pickPdf()- Opens file picker for PDF selection
Platform Configuration
Android
Add file access permissions to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
For Android 13+ (API 33+), also add:
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
iOS
Add file picker permission to ios/Runner/Info.plist:
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to select PDF files</string>
Note on Saving Images
This package saves images to files on the device. To save to the gallery, use additional packages like gallery_saver or image_gallery_saver in combination with this package.
Advanced Examples
Complete Workflow with All Features
import 'package:pdf_to_image_converter/pdf_to_image_converter.dart';
import 'package:path_provider/path_provider.dart';
Future<void> advancedPdfConversion() async {
// 1. Pick PDF
final path = await PdfPicker.pickPdf();
if (path == null) return;
final converter = PdfImageConverter();
// 2. Open and inspect
await converter.openPdf(path);
print('Pages: ${converter.pageCount}');
print('Title: ${converter.metadata?.title}');
// 3. Get all page sizes
final sizes = await converter.getAllPageSizes();
print('First page: ${sizes[0].width} x ${sizes[0].height}');
// 4. Generate thumbnails for preview
final thumbnails = await converter.renderAllThumbnails(
maxWidth: 150,
maxHeight: 200,
onProgress: (current, total) {
print('Thumbnail: $current/$total');
},
);
// 5. Render specific pages with different settings
final token = CancellationToken();
final images = await converter.renderPagesWithConfig([
PageRenderConfig(pageIndex: 0, scale: 4.0), // High quality cover
PageRenderConfig(pageIndex: 1, scale: 2.0), // Medium quality
PageRenderConfig(
pageIndex: 2,
scale: 2.0,
rotation: PageRotation.rotate90,
), // Rotated
], cancellationToken: token);
// 6. Render page range with rotation
final pages5to10 = await converter.renderPageRange(
startPage: 4,
endPage: 9,
quality: RenderQuality.medium,
rotation: PageRotation.rotate0,
);
// 7. Save with custom naming
final directory = await getApplicationDocumentsDirectory();
final saved = await converter.saveAllImages(
images,
'${directory.path}/pdf_output',
fileNamePattern: 'document_page_{index}.png',
onProgress: (current, total, success) {
print('Saved: $current/$total - ${success ? "Success" : "Failed"}');
},
);
print('Total saved: $saved images');
// 8. Clean up
await converter.closePdf();
}
Performance Optimization
Choose the right quality for your use case:
// For preview/thumbnails - Fast rendering
final preview = await converter.renderPage(0, quality: RenderQuality.thumbnail);
// For in-app display - Balanced
final display = await converter.renderPage(0, quality: RenderQuality.medium);
// For export/sharing - High quality
final export = await converter.renderPage(0, quality: RenderQuality.print);
// For archival/professional use - Maximum quality
final archival = await converter.renderPage(0, quality: RenderQuality.ultra);
Example App
For a complete working example, check the example directory. It demonstrates:
- PDF file selection with PdfPicker
- Quality presets selection
- Page rotation controls
- Page rendering with custom quality
- Page navigation with page counter
- Page range rendering
- Thumbnail generation
- Batch rendering and saving all pages
- Cancellation of operations
- Progress tracking for batch operations
- Image preview and display
- Metadata display
- Status updates and loading indicators
Run the example:
cd example
flutter pub get
flutter run
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Issues and Feedback
Please file issues, bugs, or feature requests in our issue tracker.
Performance Tips
- Choose appropriate quality: Use lower quality presets for previews and higher for final output
- Use page ranges: Instead of rendering all pages, render only what's needed
- Generate thumbnails first: Show quick previews before full rendering
- Use cancellation: Allow users to stop long operations
- Batch operations wisely: Break large PDFs into smaller chunks
- Memory management: Always call
closePdf()when done
Troubleshooting
Issue: Out of memory with large PDFs
- Solution: Use lower quality presets or render pages in smaller batches
Issue: Rendering is slow
- Solution: Use
RenderQuality.thumbnailorRenderQuality.lowfor previews, then render at higher quality only when needed
Issue: Images are blurry
- Solution: Increase quality preset (e.g.,
RenderQuality.printorRenderQuality.ultra)
Issue: Need to stop a long operation
- Solution: Use
CancellationTokenwith rendering and saving methods
Changelog
Latest Version
- Added quality presets (thumbnail, low, medium, high, print, ultra)
- Added page rotation support (0°, 90°, 180°, 270°)
- Added page range rendering
- Added thumbnail generation methods
- Added cancellation support with CancellationToken
- Added custom per-page rendering configurations
- Added PDF metadata extraction
- Added getAllPageSizes method
- Enhanced documentation with comprehensive examples
Next Goals
- Add support for text extraction from PDFs
- Add watermark support
- Add image compression options
- Add support for encrypted PDFs
- Add batch conversion from multiple PDFs