espresso3389 / pdfrx

pdfrx is yet another PDF viewer implementation that built on the top of pdfium. The plugin currently supports Android, iOS, Windows, macOS, Linux, and Web.
MIT License
62 stars 38 forks source link

Generate thumbnail from pdf #6

Closed Aerofluxx closed 5 months ago

Aerofluxx commented 5 months ago

Hello,

I'm trying to switch from pdf_render over to pdfrx but having some troubles doing this.

My "old" thumbnail generation was something like this

import 'package:pdf_render/pdf_render.dart';

Future<Uint8List?> createPdfThumbnail(Uint8List fileData) async {
  final PdfDocument doc = await PdfDocument.openData(fileData);
  final PdfPage page = await doc.getPage(1);

  PdfPageImage pageImage;

  if (page.width > page.height) {
    pageImage = await page.render(
      fullWidth: maxSideSize,
      fullHeight: (page.height * maxSideSize / page.width),
    );
  } else {
    pageImage = await page.render(
      fullHeight: maxSideSize,
      fullWidth: (page.width * maxSideSize / page.height),
    );
  }

  // Convert PdfPageImage to ui.Image
  final ui.Image uiImage = await pageImage.createImageIfNotAvailable();

  // Convert ui.Image to img.Image for further processing
  final img.Image finalImage = await convertUiImageToImgImage(uiImage);

  doc.dispose();

  return img.encodeJpg(finalImage);
}

Changing to pdfrx it will be

import 'package:pdfrx/pdfrx.dart';

Future<Uint8List?> createPdfThumbnail(Uint8List fileData) async {
  final PdfDocument doc = await PdfDocument.openData(fileData);
  final PdfPage page = await doc.getPage(1);

  PdfImage pageImage;

  if (page.width > page.height) {
    pageImage = await page.render(
      fullWidth: maxSideSize,
      fullHeight: (page.height * maxSideSize / page.width),
    );
  } else {
    pageImage = await page.render(
      fullHeight: maxSideSize,
      fullWidth: (page.width * maxSideSize / page.height),
    );
  }

  // Convert PdfPageImage to ui.Image
  final ui.Image uiImage = await pageImage.createImage();

  // Convert ui.Image to img.Image for further processing
  final img.Image finalImage = await convertUiImageToImgImage(uiImage);

  doc.dispose();

  return img.encodeJpg(finalImage);
}

And getting this error (but only in flutter for web, working fine on MacOS build)

TypeError: Cannot perform %TypedArray%.prototype.set on a detached ArrayBuffer
dart-sdk/lib/_internal/js_dev_runtime/private/native_typed_data.dart 691:31  [_setRangeFast]
dart-sdk/lib/_internal/js_dev_runtime/private/native_typed_data.dart 735:7   setRange
dart-sdk/lib/convert/byte_conversion.dart 81:5                               add
dart-sdk/lib/async/zone.dart 1594:9                                          runUnaryGuarded
dart-sdk/lib/async/stream_impl.dart 339:5                                    [_sendData]
dart-sdk/lib/async/stream_impl.dart 271:7                                    [_add]
dart-sdk/lib/async/stream_transformers.dart 63:11                            [_add]
dart-sdk/lib/async/stream_transformers.dart 13:5                             add
packages/dio/src/progress_stream/browser_progress_stream.dart 33:15          <fn>
dart-sdk/lib/async/stream_transformers.dart 209:7                            add
dart-sdk/lib/async/stream_transformers.dart 111:7                            [_handleData]
dart-sdk/lib/async/zone.dart 1594:9                                          runUnaryGuarded
dart-sdk/lib/async/stream_impl.dart 339:5                                    [_sendData]
dart-sdk/lib/async/stream_impl.dart 515:13                                   perform
dart-sdk/lib/async/stream_impl.dart 620:10                                   handleNext
dart-sdk/lib/async/stream_impl.dart 591:7                                    callback
dart-sdk/lib/async/schedule_microtask.dart 40:11                             _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5                              _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7           <fn>
espresso3389 commented 5 months ago

0.2.3 is a new release that fixes the PdfPage.render (Web)'s behavior difference from other platforms. Please check it.

Aerofluxx commented 5 months ago

Hey :)

I'm sorry but I'm still getting

TypeError: Cannot perform %TypedArray%.prototype.set on a detached ArrayBuffer
dart-sdk/lib/_internal/js_dev_runtime/private/native_typed_data.dart 691:31  [_setRangeFast]
dart-sdk/lib/_internal/js_dev_runtime/private/native_typed_data.dart 735:7   setRange
dart-sdk/lib/convert/byte_conversion.dart 81:5                               add
dart-sdk/lib/async/zone.dart 1594:9                                          runUnaryGuarded
dart-sdk/lib/async/stream_impl.dart 339:5                                    [_sendData]
dart-sdk/lib/async/stream_impl.dart 271:7                                    [_add]
dart-sdk/lib/async/stream_transformers.dart 63:11                            [_add]
dart-sdk/lib/async/stream_transformers.dart 13:5                             add
packages/dio/src/progress_stream/browser_progress_stream.dart 33:15          <fn>
dart-sdk/lib/async/stream_transformers.dart 209:7                            add
dart-sdk/lib/async/stream_transformers.dart 111:7                            [_handleData]
dart-sdk/lib/async/zone.dart 1594:9                                          runUnaryGuarded
dart-sdk/lib/async/stream_impl.dart 339:5                                    [_sendData]
dart-sdk/lib/async/stream_impl.dart 515:13                                   perform
dart-sdk/lib/async/stream_impl.dart 620:10                                   handleNext
dart-sdk/lib/async/stream_impl.dart 591:7                                    callback
dart-sdk/lib/async/schedule_microtask.dart 40:11                             _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5                              _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7           <fn>

on the same code that works without any probs on MacOS Build.

Can i provide you with any further information for debugging? Just let me know :)

Thank you!

Edit:

Just to let u know, I'm having this in my index.html and also made a flutter clean before I've tried it again.

  <!-- IMPORTANT: load pdfjs files -->
  <script src="https://cdn.jsdelivr.net/npm/pdfjs-dist@3.11.174/build/pdf.min.js" type="text/javascript"></script>
  <script type="text/javascript">
    pdfjsLib.GlobalWorkerOptions.workerSrc =
      "https://cdn.jsdelivr.net/npm/pdfjs-dist@3.11.174/build/pdf.worker.min.js";
    pdfRenderOptions = {
      // where cmaps are downloaded from
      cMapUrl: "https://cdn.jsdelivr.net/npm/pdfjs-dist@3.11.174/cmaps/",
      // The cmaps are compressed in the case
      cMapPacked: true,
      // any other options for pdfjsLib.getDocument.
      // params: {}
    };
  </script>
Aerofluxx commented 5 months ago

Any news / ideas on this topic @espresso3389? :)

espresso3389 commented 5 months ago

I don't know what's happening on your code but the log shows me that the error is caused by dio package.

packages/dio/src/progress_stream/browser_progress_stream.dart 33:15

pdfrx does not depend on dio and it may be caused by CORS or something?

Aerofluxx commented 5 months ago

Got you!

Strangest thing for me is, that the same code is working fine with your pdf_render package. There I'm getting no dio errors, which means to me, that pdfrx does something different in web on creating the image.

Also same code works fine on MacOS build. I can exclude a CORS problem (disabled security for debugging locally).

Aerofluxx commented 5 months ago

Goooooosh ... thank you for the kind tip. I was blind or something.

I had to deep copy my Uint8List file bytes because after handling the createPdfThumbnail, the original bytes array was empty.