【问题标题】:Rendering multiple pages of pdf to single Canvas using pdf.js and ImageData使用 pdf.js 和 ImageData 将多页 pdf 渲染到单个 Canvas
【发布时间】:2013-11-18 04:49:42
【问题描述】:

我正在尝试将 pdf 渲染到单个画布上,我参考了以下链接来实现相同的操作。

访问:Render .pdf to single Canvas using pdf.js and ImageData

var pdf = null;

    PDFJS.disableWorker = true;
    var pages = new Array();
   var canvas = document.getElementById('the-canvas');
    var context = canvas.getContext('2d');
    var scale = 1.5;
    var canvasWidth = 0;
    var canvasHeight = 0;
    var pageStarts = new Array();
    pageStarts[0] = 0;


    PDFJS.getDocument(url).then(function getPdfHelloWorld(_pdf) {
        debugger;
        pdf = _pdf;
        //Render all the pages on a single canvas
        for (var pNum = 1; pNum <= pdf.numPages; pNum++) {
            pdf.getPage(pNum).then(function getPage(page) {
                var viewport = page.getViewport(scale);
                canvas.width = viewport.width;
                canvas.height = viewport.height;
                page.render({ canvasContext: context, viewport: viewport });
                pages[pNum - 1] = context.getImageData(0, 0, canvas.width, canvas.height);
                canvasHeight += canvas.height;
                pageStarts[i] = pageStarts[i - 1] + canvas.height;


            });
        }

        canvas.width = canvasWidth;
        canvas.height = canvasHeight;

        for (var i = 0; i < pages.length; i++) {
            context.putImageData(pages[i], 0, pageStarts[i]);
        }
    });

我看到空间被创建来呈现不显示 pdf 的页面。

任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: javascript html5-canvas pdf.js getimagedata putimagedata


    【解决方案1】:

    您用于存储 pageStarts 的代码引用“i”,就好像它是一个迭代器索引一样,但它位于使用 pNum 的 for 语句中。我很惊讶这段代码不会在控制台中抛出错误,将您指向可能的解决方案。你应该改变:

    canvasHeight += canvas.height;
    pageStarts[i] = pageStarts[i - 1] + canvas.height;
    

    类似于:

    pageStarts[pNum - 1] = canvasHeight;
    canvasHeight += canvas.height;
    

    请注意,在您获取“最后一个”值之前,我重新组织了 canvasHeight 计算。这将允许您确定当前页面图像数据的正确起始高度,而无需在上一次迭代中使用 pageStart。

    这是一个未经测试的解决方案,因为您没有发布其余代码,但它应该会引导您找到您的解决方案。

    【讨论】:

    • 我所有的页面都相互重叠,有些甚至是倒置的。我确实对原始代码进行了更改以更正索引。对于如何解决这个问题,有任何的建议吗?代码 sn-p 在这里:gist.github.com/hetalv985/54f7165d2836dd4d62877ed9277a5640
    • @HetalVora,您需要添加一些基本的调试语句或在调试器中执行您的代码。我想您会发现像这样的语句:“pages[pages.length] = ...”没有预期的行为,因为您从未设置 pages 数组的长度,也没有向其中添加任何项目。上面列出的代码和上面问题中引用的原始代码都使用 pNum-1 或 i-1 方法作为数组索引。您的代码试图将每个图像都放在 0,0 处。此外,请在代码中的制表符和空格之间保持一致。看到两者都令人沮丧。
    【解决方案2】:

    这是带有 textLayer 的多页面视图

    <script type="text/javascript">
    window.onload = function () {
      var url = '[[*pdf]]';
      var scale = 1.1; //Set this to whatever you want. This is basically the "zoom" factor for the PDF.
      var currPage = 1; //Pages are 1-based not 0-based
      var numPages = 0;
      var thePDF = null;
      PDFJS.workerSrc = '/js/build/pdf.worker.js';
      PDFJS.getDocument(url).then(function(pdf){
        thePDF = pdf;
        numPages = pdf.numPages;
        pdf.getPage(1).then(handlePages);
      });
      function handlePages(page){
        var viewport = page.getViewport(scale);
        var pdfPage = document.createElement('div');
        pdfPage.className = 'pdfPage';
        var pdfContainer = document.getElementById('pdfContainer');
    
        var canvas = document.createElement( "canvas" );
        canvas.style.display = "block";
        var context = canvas.getContext('2d');
        var outputScale = getOutputScale(context);
        canvas.width = (Math.floor(viewport.width) * outputScale.sx) | 0;
        canvas.height = (Math.floor(viewport.height) * outputScale.sy) | 0;
        context._scaleX = outputScale.sx;
        context._scaleY = outputScale.sy;
        if (outputScale.scaled) {
          context.scale(outputScale.sx, outputScale.sy);
        }
    
        // The page, canvas and text layer elements will have the same size.
        canvas.style.width = Math.floor(viewport.width) + 'px';
        canvas.style.height = Math.floor(viewport.height) + 'px';
    
        pdfPage.style.width = canvas.style.width;
        pdfPage.style.height = canvas.style.height;
        pdfPage.appendChild(canvas);
    
        var textLayerDiv = document.createElement('div');
        textLayerDiv.className = 'textLayer';
        textLayerDiv.style.width = canvas.style.width;
        textLayerDiv.style.height = canvas.style.height;
        pdfPage.appendChild(textLayerDiv);
    
        page.render({canvasContext: context, viewport: viewport});
    
        var textLayerPromise = page.getTextContent().then(function (textContent) {
          var textLayerBuilder = new TextLayerBuilder({
            textLayerDiv: textLayerDiv,
            viewport: viewport,
            pageIndex: 0
          });
          textLayerBuilder.setTextContent(textContent);
        });
    
        pdfContainer.appendChild(pdfPage);
    
        currPage++;
        if ( thePDF !== null && currPage <= numPages ){thePDF.getPage( currPage ).then( handlePages );}
      }
    }
    </script>
    

    【讨论】:

    • 谢谢。您应该包含您的 html 和 css,以明确您正在使用的元素。
    • 另外,getOutputScale 未定义。
    猜你喜欢
    • 1970-01-01
    • 2017-10-28
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 2015-04-12
    • 2012-07-23
    • 2013-08-06
    • 2019-12-28
    相关资源
    最近更新 更多