100 lines
3.1 KiB
Dart
100 lines
3.1 KiB
Dart
|
|
// lib/services/pdf_snapshot_service.dart
|
||
|
|
|
||
|
|
import 'dart:io';
|
||
|
|
import 'dart:ui' as ui;
|
||
|
|
import 'package:flutter/foundation.dart';
|
||
|
|
import 'package:pdf_render/pdf_render.dart';
|
||
|
|
|
||
|
|
class PdfSnapshotService {
|
||
|
|
/// Merender halaman pertama berkas PDF menjadi berkas gambar PNG lokal.
|
||
|
|
/// Mengembalikan path berkas PNG jika berhasil, atau null jika gagal.
|
||
|
|
static Future<String?> renderFirstPage({
|
||
|
|
required String pdfPath,
|
||
|
|
required String outputPngPath,
|
||
|
|
double scale = 2.0,
|
||
|
|
}) async {
|
||
|
|
try {
|
||
|
|
final file = File(pdfPath);
|
||
|
|
if (!file.existsSync()) {
|
||
|
|
debugPrint('PdfSnapshotService: File tidak ditemukan di $pdfPath');
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
final document = await PdfDocument.openFile(pdfPath);
|
||
|
|
if (document.pageCount < 1) {
|
||
|
|
await document.dispose();
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
final page = await document.getPage(1);
|
||
|
|
final renderWidth = (page.width * scale).toInt();
|
||
|
|
final renderHeight = (page.height * scale).toInt();
|
||
|
|
|
||
|
|
final pageImage = await page.render(
|
||
|
|
width: renderWidth,
|
||
|
|
height: renderHeight,
|
||
|
|
);
|
||
|
|
|
||
|
|
final uiImg = await pageImage.createImageDetached();
|
||
|
|
final byteData = await uiImg.toByteData(format: ui.ImageByteFormat.png);
|
||
|
|
pageImage.dispose();
|
||
|
|
await document.dispose();
|
||
|
|
|
||
|
|
if (byteData != null && byteData.lengthInBytes > 0) {
|
||
|
|
final outputFile = File(outputPngPath);
|
||
|
|
await outputFile.writeAsBytes(byteData.buffer.asUint8List());
|
||
|
|
return outputFile.path;
|
||
|
|
}
|
||
|
|
} catch (e) {
|
||
|
|
debugPrint('PdfSnapshotService.renderFirstPage error: $e');
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Merender beberapa halaman PDF menjadi daftar berkas gambar PNG lokal.
|
||
|
|
static Future<List<String>> renderPages({
|
||
|
|
required String pdfPath,
|
||
|
|
required String outputBasePngPath,
|
||
|
|
double scale = 2.0,
|
||
|
|
int maxPages = 5,
|
||
|
|
}) async {
|
||
|
|
final List<String> renderedPaths = [];
|
||
|
|
try {
|
||
|
|
final file = File(pdfPath);
|
||
|
|
if (!file.existsSync()) return renderedPaths;
|
||
|
|
|
||
|
|
final document = await PdfDocument.openFile(pdfPath);
|
||
|
|
final pageCount = document.pageCount;
|
||
|
|
final pagesToRender = pageCount < maxPages ? pageCount : maxPages;
|
||
|
|
|
||
|
|
for (int i = 1; i <= pagesToRender; i++) {
|
||
|
|
final page = await document.getPage(i);
|
||
|
|
final renderWidth = (page.width * scale).toInt();
|
||
|
|
final renderHeight = (page.height * scale).toInt();
|
||
|
|
|
||
|
|
final pageImage = await page.render(
|
||
|
|
width: renderWidth,
|
||
|
|
height: renderHeight,
|
||
|
|
);
|
||
|
|
|
||
|
|
final uiImg = await pageImage.createImageDetached();
|
||
|
|
final byteData = await uiImg.toByteData(format: ui.ImageByteFormat.png);
|
||
|
|
pageImage.dispose();
|
||
|
|
|
||
|
|
if (byteData != null && byteData.lengthInBytes > 0) {
|
||
|
|
final targetPath = '${outputBasePngPath}_p$i.png';
|
||
|
|
final outputFile = File(targetPath);
|
||
|
|
await outputFile.writeAsBytes(byteData.buffer.asUint8List());
|
||
|
|
renderedPaths.add(outputFile.path);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
await document.dispose();
|
||
|
|
} catch (e) {
|
||
|
|
debugPrint('PdfSnapshotService.renderPages error: $e');
|
||
|
|
}
|
||
|
|
return renderedPaths;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|