syncfusion / flutter-widgets

Syncfusion Flutter widgets libraries include high quality UI widgets and file-format packages to help you create rich, high-quality applications for iOS, Android, and web from a single code base.
1.48k stars 702 forks source link

How to get the first page to preview it as a thumbnail #1879

Open batoul-alani opened 1 month ago

batoul-alani commented 1 month ago

Use case

Need to display a thumbnail of the selected PDF. I couldn't find a way to extract the first page for thumbnail display.the

Proposal

.

SittiphanSittisak commented 2 weeks ago

I need it too. I need to show the PDF preview for my file uploader. This package can show the PDF like the thumbnail but uses too much performance. It loads all the pages of this PDF. I want just the first page without a scroll. image

immankumarsync commented 2 weeks ago

At present, we don't have support to extract the thumbnail of the first page. However, you can create the thumbnail using the code below.

  1. Add syncfusion_flutter_pdfviewer dependency
dependencies:
  flutter:
    sdk: flutter
  syncfusion_flutter_pdfviewer: ^26.1.38
  1. Import 'syncfusion_pdfviewer_platform_interface' library
import 'package:syncfusion_pdfviewer_platform_interface/pdfviewer_platform_interface.dart';
  1. Code to generate thumbnail image of the first page.
    
    import 'dart:async';
    import 'dart:ui' as ui;

import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:syncfusion_pdfviewer_platform_interface/pdfviewer_platform_interface.dart';

void main() { runApp(const MainApp()); }

class MainApp extends StatelessWidget { const MainApp({ super.key, });

@override Widget build(BuildContext context) { return const MaterialApp( title: 'Syncfusion PDF Viewer Demo', home: ThumbnailPage(), ); } }

class ThumbnailPage extends StatefulWidget { const ThumbnailPage({super.key});

@override State createState() => _ThumbnailPageState(); }

class _ThumbnailPageState extends State { Widget? _thumbnailWidget;

@override Widget build(BuildContext context) { return Scaffold( body: Center( child: SingleChildScrollView( child: Column( children: [ if (_thumbnailWidget != null) _thumbnailWidget!, ElevatedButton( onPressed: _getThumbnail, child: const Text('Generate thumbnail'), ), ElevatedButton( onPressed: () { setState(() { _thumbnailWidget = null; }); }, child: const Text('Clear thumbnail'), ), ], ), ), ), ); }

void _getThumbnail() async { //Load the PDF document final byteData = await rootBundle.load('assets/flutter-succinctly.pdf'); final bytes = byteData.buffer.asUint8List();

String documentID = '1';
int pageNumber = 1;
// Initialize the PDF renderer
await PdfViewerPlatform.instance.initializePdfRenderer(bytes, documentID);
// Get the height and width of all the pages
final pagesHeight =
    await PdfViewerPlatform.instance.getPagesHeight(documentID);
final pagesWidth =
    await PdfViewerPlatform.instance.getPagesWidth(documentID);

// Calculate the aspect ratio of the first page
final ratio = pagesWidth![pageNumber] / pagesHeight![pageNumber];

// Calculate the thumbnail width and height
const int thumbnailWidth = 200;
final int thumbnailHeight = (thumbnailWidth / ratio).toInt();

// Get the thumbnail image bytes
final imageBytes = await PdfViewerPlatform.instance
    .getPage(1, thumbnailWidth, thumbnailHeight, documentID);
// Close the document
await PdfViewerPlatform.instance.closeDocument(documentID);

if (imageBytes == null) {
  return;
}
final thumbnail = FutureBuilder<ui.Image>(
  future: _createImage(
    imageBytes,
    thumbnailWidth,
    thumbnailHeight,
  ),
  builder: (context, snapshot) {
    if (snapshot.hasData && snapshot.data != null) {
      return SizedBox(
        width: thumbnailWidth.toDouble(),
        height: thumbnailHeight.toDouble(),
        child: RawImage(
          image: snapshot.data!,
        ),
      );
    }
    return const CircularProgressIndicator();
  },
);

setState(() {
  _thumbnailWidget = thumbnail;
});

}

// Create an image from the raw bytes Future _createImage(Uint8List pixels, int width, int height) { final Completer comp = Completer(); ui.decodeImageFromPixels(pixels, width, height, ui.PixelFormat.rgba8888, (ui.Image image) => comp.complete(image));

return comp.future;

} }



Please confirm us whether the code meets your requirement.