30

我正在使用 PDF.JS 将 pdf 页面呈现到不同的画布元素中。我的要求是捕获画布的输出并将其显示为图像。是否有一些事件可以知道画布中 pdf 页面的渲染是否已经完成。因为当我尝试捕获画布的输出时,它是空白的。但pdf页面正确呈现。看起来我的捕获事件在 pdf.js 完成渲染过程之前被调用。

这是我的代码:

page.render(renderContext);
var myImage = new Image();
myImage.src = document.getElementById('my-canvas-id').toDataURL();
$('body').append(myImage);

如果我在我的 FireFox 控制台中执行相同的代码,它就可以正常工作。所以这段代码没有任何问题。

只是为了让大家知道我已经尝试过 document.ready 和 window.load 事件。

4

16 回答 16

22

我也在努力解决这个问题..我使用的解决方案是:

//Step 1: store a refer to the renderer
var pageRendering = page.render(renderContext);
//Step : hook into the pdf render complete event
var completeCallback = pageRendering.internalRenderTask.callback;
pageRendering.internalRenderTask.callback = function (error) {
  //Step 2: what you want to do before calling the complete method                  
  completeCallback.call(this, error);
  //Step 3: do some more stuff
};
于 2013-09-03T05:03:24.163 回答
18

<script type="text/javascript">
  document.addEventListener("pagesloaded", function(e) {
   //do sth..
  });
</script>

为我工作

于 2015-03-31T22:37:44.493 回答
16

在撰写本文时,这确实有效。我不确定它是否仍然存在。

PDFJS 使用Promises. 最简单的方法如下:

page.render(renderContext).promise.then(function(){
  document.body.appendChild(canvas);
});
于 2013-07-13T13:52:24.537 回答
7

使用该textlayerrendered事件对我有用:

document.addEventListener('textlayerrendered', function (event) {
  // was this the last page?
  if (event.detail.pageNumber === PDFViewerApplication.page) {
    console.log('Finished rendering!');
  }
}, true);
于 2015-09-15T17:21:18.850 回答
4

里昂的解决方案更健壮。但这是我能找到的最简单的解决方案。

var renderTask = pdfPage.render(renderContext);
renderTask.promise.then(
  function pdfPageRenderCallback() {
    pageViewDrawCallback(null);
  },
  function pdfPageRenderError(error) {
    pageViewDrawCallback(error);
  }
);
于 2014-02-10T17:52:01.667 回答
3

在检查这些解决方案时,我遇到了问题renderContext,所以我最终使用这种方法来听pagerendered

document.addEventListener("pagerendered", function(e){

});

在我的例子中,我只是想在页面渲染后调用一些外部函数,而且工作量很小。

希望这可以帮助。干杯!

于 2015-03-16T17:27:17.230 回答
3
window.addEventListener('load', function () {
    PDFViewerApplication.eventBus.on('textlayerrendered', function () {
      console.log('textlayerrendered', arguments, PDFViewerApplication)
    })

事件名称textlayerrendered包括PDFViewerApplication.eventBus._listeners

于 2020-10-21T14:04:02.210 回答
2

事实证明,您的第一行page.render(renderContext);返回一个RenderTask具有 3 个属性的对象:

  • internalRenderTask - 一个InternalRenderTask,呃
  • cancel - 一个函数,可能允许您取消渲染工作
  • promise - 一个 jQueryPromise对象

承诺是你想要的。要使用它,它是这样的:

 page.render(renderContext).promise.then(function() {

     //do something after the page is rendered here
 });

希望有帮助。

于 2014-06-13T21:21:17.107 回答
2

如果您将 pdf.js 与查看器应用程序一起使用,这是我发现等待其初始化的最佳方法:

// Wait for the PDFViewerApplication to initialize                                                                                                                         
PDFViewerApplication.initializedPromise.then(function() {
    // Do whatever startup code you need to here, now that the EventBus
    // is read. For example:
    PDFViewerApplication.eventBus.on('pagerendered', function (e) {
        annotationInterface.onPageRendered(e);
    });
});
于 2021-07-22T17:21:20.947 回答
2

根据PDF.js的文档。

对于 2.2 之前的版本,请使用:
page.render(renderContext).then(function(){
var myImage = new Image();
myImage.src = document.getElementById('my-canvas-id').toDataURL();
$('body').append(myImage);
});

对于 2.2 之后的版本(包括 2.2),请使用: page.render(renderContext).promise.then(function(){
var myImage = new Image();
myImage.src = document.getElementById('my-canvas-id').toDataURL();
$('body').append(myImage);
});

于 2021-01-07T18:18:55.357 回答
1

我以这种方式更改了我的代码,它帮助了我想要做的事情:

pageRendering = page.render(renderContext);
pageRendering.onData(function(){
    var myImage = new Image();
    myImage.src = document.getElementById('my-canvas-id').toDataURL();
    $('body').append(myImage);
});

这仅在特定页面已完成渲染时才有帮助。它不会告诉您所有页面的呈现。

于 2012-10-04T09:30:47.697 回答
1

如果您想在不同的画布中渲染 pdf 文档的所有页面,所有这些页面都是同步的,这是一种解决方案:

索引.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>PDF Sample</title>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="pdf.js"></script>
    <script type="text/javascript" src="main.js">
    </script>
    <link rel="stylesheet" type="text/css" href="main.css">
</head>
<body id="body">  
</body>
</html>

main.css

canvas {
    display: block;
}

main.js

$(function() {  
    var filePath = "document.pdf";

    function Num(num) {
        var num = num;

        return function () {
            return num;
        }
    };

    function renderPDF(url, canvasContainer, options) {
        var options = options || {
                scale: 1.5
            },          
            func,
            pdfDoc,
            def = $.Deferred(),
            promise = $.Deferred().resolve().promise(),         
            width, 
            height,
            makeRunner = function(func, args) {
                return function() {
                    return func.call(null, args);
                };
            };

        function renderPage(num) {          
            var def = $.Deferred(),
                currPageNum = new Num(num);
            pdfDoc.getPage(currPageNum()).then(function(page) {
                var viewport = page.getViewport(options.scale);
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                var renderContext = {
                    canvasContext: ctx,
                    viewport: viewport
                };

                if(currPageNum() === 1) {                   
                    height = viewport.height;
                    width = viewport.width;
                }

                canvas.height = height;
                canvas.width = width;

                canvasContainer.appendChild(canvas);

                page.render(renderContext).then(function() {                                        
                    def.resolve();
                });
            })

            return def.promise();
        }

        function renderPages(data) {
            pdfDoc = data;

            var pagesCount = pdfDoc.numPages;
            for (var i = 1; i <= pagesCount; i++) { 
                func = renderPage;
                promise = promise.then(makeRunner(func, i));
            }
        }

        PDFJS.disableWorker = true;
        PDFJS.getDocument(url).then(renderPages);       
    };

    var body = document.getElementById("body");
    renderPDF(filePath, body);
});
于 2014-06-06T00:17:45.270 回答
1

根据您使用的 PDF.js 的组件(和版本),您还可以使用 EventBus。

如果您使用的是最简单的 PDF.js 实现,那么这可能不可用,但如果您使用的是他们的SimpleViewer 或 PageViewer 示例,请尝试以下操作:

        eventBus.on("pagesloaded", function() {
            console.log('pagesloaded');
            // your code here
        });

eventBus 应该已经定义,如果没有,您可以使用以下方法进行设置:

var eventBus = new pdfjsViewer.EventBus();

同样,这取决于您的 PDF 查看器的复杂程度。事实证明 PDF.js 中有许多不同的层。

要监听每个页面加载,请使用 eventBus 事件“ pagerendered

于 2020-07-02T16:39:32.787 回答
0

这是我发现使用 Viewer API 并无错误操作呈现页面的唯一方法。

onPagesLoaded = () => { 
    // do something, set zoom, current page, ...
};

window.PDFViewerApplication.eventBus.on('pagesloaded', onPagesLoaded);
于 2022-01-05T10:32:59.113 回答
0

page.render 是一个承诺,所以你必须在你的成功中做你的事情,如下所示:

page.render({
  canvasContext: context,
  viewport: viewport
}).then(function() {
//do your stuff here });
于 2016-11-18T15:04:45.080 回答
0

如果您在后端创建/修改 PDF,您可以将 pdf javascript 添加到 PDF 文件以在加载时打印。

var pp = getPrintParams();  
pp.interactive=pp.constants.interactionLevel.full; 
print(pp);
于 2022-01-07T20:12:30.180 回答