Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
batoul-alani opened this issue May 22, 2024 · 5 comments
Open

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

batoul-alani opened this issue May 22, 2024 · 5 comments
Labels
pdf viewer PDF viewer component waiting for customer response Cannot make further progress until the customer responds.

Comments

@batoul-alani
Copy link

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

.

@VijayakumarMariappan VijayakumarMariappan added pdf PDF component pdf viewer PDF viewer component open Open labels May 23, 2024
@SittiphanSittisak
Copy link

SittiphanSittisak commented Jun 19, 2024

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
Copy link
Contributor

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<ThumbnailPage> createState() => _ThumbnailPageState();
}

class _ThumbnailPageState extends State<ThumbnailPage> {
  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<ui.Image> _createImage(Uint8List pixels, int width, int height) {
    final Completer<ui.Image> comp = Completer<ui.Image>();
    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.

@chinnumuniyappan chinnumuniyappan removed the pdf PDF component label Jul 5, 2024
@Deepak1799 Deepak1799 added waiting for customer response Cannot make further progress until the customer responds. and removed open Open labels Jul 5, 2024
@loveoverflowdev
Copy link

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<ThumbnailPage> createState() => _ThumbnailPageState();
}

class _ThumbnailPageState extends State<ThumbnailPage> {
  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<ui.Image> _createImage(Uint8List pixels, int width, int height) {
    final Completer<ui.Image> comp = Completer<ui.Image>();
    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.

This code is helpful to me now.
However, it seems to lack documentation, and in my testing, the page index started at 1 instead of the usual 0.
Additionally, the future doesn't complete when occurring index error (as 0 passed for index param), without any exception.

@kmarellapudi
Copy link

kmarellapudi commented Aug 24, 2024

await PdfViewerPlatform.instance.closeDocument(documentID) fails silently and the execution stops. If this line is removed, for testing, the execution continues to create the image. Please advise.

@immankumarsync
Copy link
Contributor

@kmarellapudi, can you let me know in which platform the error occurred?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pdf viewer PDF viewer component waiting for customer response Cannot make further progress until the customer responds.
Projects
None yet
Development

No branches or pull requests

8 participants