I'm developing a Flutter app where I need to convert a multi-page PDF into images and then share these images. I'm using the pdf_image_renderer package for rendering the PDF pages to images and share_plus for sharing. However, I'm encountering an issue where, despite having multiple pages in the PDF, only the first page's image is shared twice.
convertPdfToImages
: This function should convert each page of a PDF into an image, but it's currently sharing images of only the first page.
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdf_image_renderer/pdf_image_renderer.dart' as pdf_renderer;
import 'package:share_plus/share_plus.dart';
Future<List<XFile>> convertPdfToImages(Uint8List pdfBytes, String title) async {
final pdfFile = File('${(await getTemporaryDirectory()).path}/temp.pdf');
await pdfFile.writeAsBytes(pdfBytes);
final pdfDocument = pdf_renderer.PdfImageRendererPdf(path: pdfFile.path);
await pdfDocument.open();
final pageCount = await pdfDocument.getPageCount();
final List<XFile> imageFiles = [];
for (int i = 0; i < pageCount; i++) {
try {
final size = await pdfDocument.getPageSize(pageIndex: i);
final pdfImage = await pdfDocument.renderPage(
x: 0,
y: 0,
width: size.width.toInt(),
height: size.height.toInt(),
scale: 1.0,
background: Colors.transparent,
);
if (pdfImage != null) {
final imageFile = File('${(await getTemporaryDirectory()).path}/${title}_page_${i + 1}.png');
await imageFile.writeAsBytes(pdfImage);
imageFiles.add(XFile(imageFile.path));
} else {
print('Failed to render page $i');
}
} catch (e) {
print('Error processing page $i: $e');
}
}
await pdfDocument.close();
pdfFile.delete();
return imageFiles;
}
shareAsImages
: This function calls convertPdfToImages and then shares the images.
Future<void> shareAsImages(Map<String, dynamic> data) async {
final pdfBytes = await _generatePdf(data);
final imageFiles = await convertPdfToImages(pdfBytes, data['title']);
await Share.shareXFiles(
imageFiles,
text: 'Created using: ${constants.CommonUrls.appPlaystoreUrl}',
);
}
_generatePdf
: This function generates a multi-page PDF. Here's a simplified version:
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
Future<Uint8List> _generatePdf(Map<String, dynamic> data) async {
final pdf = pw.Document();
pdf.addPage(
pw.MultiPage(
build: (pw.Context context) {
return [
pw.Text('${data['title']}', style: pw.TextStyle(fontSize: 24, fontWeight: pw.FontWeight.bold)),
pw.SizedBox(height: 16),
pw.Text('Course: ${data['course']}'),
pw.Text('Category: ${data['category']}'),
pw.Text('Serving Size: ${data['serveSize']}'),
pw.Text('Preparation Time: ${data['prepTime']}'),
pw.Text('Cooking Time: ${data['cookingTime']}'),
if (data['rating'] != null && double.tryParse(data['rating'].toString()) != 0.0) ...[
pw.Text('Rating: ${data['rating']}'),
],
pw.Text('Source: ${data['source']}'),
pw.SizedBox(height: 16),
pw.Text('Ingredients:', style: pw.TextStyle(fontSize: 20, fontWeight: pw.FontWeight.bold)),
pw.Text(data['ingredients'] ?? ''),
pw.SizedBox(height: 16),
pw.Text('Instructions:', style: pw.TextStyle(fontSize: 20, fontWeight: pw.FontWeight.bold)),
pw.Text(data['instructions'] ?? ''),
if (data['notes'] != null && data['notes'].isNotEmpty) ...[
pw.SizedBox(height: 16),
pw.Text('Notes:', style: pw.TextStyle(fontSize: 20, fontWeight: pw.FontWeight.bold)),
pw.Text(data['notes'] ?? ''),
],
if (data['nutrition']['show'] == true && data['nutrition'].entries.any((e) => e.value != null && e.value.isNotEmpty)) ...[
pw.SizedBox(height: 16),
pw.Text('Nutrition Info:', style: pw.TextStyle(fontSize: 20, fontWeight: pw.FontWeight.bold)),
pw.Text('Per Serve Size: ${data['nutrition']['serveSize'] ?? ''}'),
pw.Text('Calories: ${data['nutrition']['calories'] ?? ''}'),
pw.Text('Total Fat: ${data['nutrition']['totalFat'] ?? ''}'),
pw.Text('Saturated Fat: ${data['nutrition']['saturatedFat'] ?? ''}'),
pw.Text('Cholesterol: ${data['nutrition']['cholesterol'] ?? ''}'),
pw.Text('Sodium: ${data['nutrition']['sodium'] ?? ''}'),
pw.Text('Total Carbohydrate: ${data['nutrition']['totalCarbohydrate'] ?? ''}'),
pw.Text('Dietary Fiber: ${data['nutrition']['dietaryFiber'] ?? ''}'),
pw.Text('Sugars: ${data['nutrition']['sugars'] ?? ''}'),
pw.Text('Protein: ${data['nutrition']['protein'] ?? ''}'),
],
];
},
),
);
return pdf.save();
}
Issue: Despite having multiple pages in the PDF, the convertPdfToImages function is currently sharing only the first page's image twice and missing the second page.
Actually I was missing pageIndex: i,
final pdfImage = await pdfDocument.renderPage(
pageIndex: i, // This Line
x: 0,
y: 0,
width: size.width.toInt(),
height: size.height.toInt(),
scale: 1.0,
background: Colors.transparent,
);