编程语言
首页 > 编程语言> > javascript – 使用pdf.js和ImageData将.pdf渲染为单个Canvas

javascript – 使用pdf.js和ImageData将.pdf渲染为单个Canvas

作者:互联网

我试图使用PDF.js读取整个.pdf文档,然后在单个画布上渲染所有页面.

我的想法:将每个页面渲染到画布上并获取ImageData(context.getImageData()),清除画布做下一页.我将所有ImageDatas存储在一个数组中,一旦所有页面都在那里,我想将数组中的所有ImageDatas放到一个画布上.

var pdf = null;
PDFJS.disableWorker = true;
var pages = new Array();
    //Prepare some things
    var canvas = document.getElementById('cv');
    var context = canvas.getContext('2d');
    var scale = 1.5;
    PDFJS.getDocument(url).then(function getPdfHelloWorld(_pdf) {
        pdf = _pdf;
        //Render all the pages on a single canvas
        for(var i = 1; i <= pdf.numPages; i ++){
            pdf.getPage(i).then(function getPage(page){
                var viewport = page.getViewport(scale);
                canvas.width = viewport.width;
                canvas.height = viewport.height;
                page.render({canvasContext: context, viewport: viewport});
                pages[i-1] = context.getImageData(0, 0, canvas.width, canvas.height);
                context.clearRect(0, 0, canvas.width, canvas.height);
                p.Out("pre-rendered page " + i);
            });
        }

    //Now we have all 'dem Pages in "pages" and need to render 'em out
    canvas.height = 0;
    var start = 0;
    for(var i = 0; i < pages.length; i++){
        if(canvas.width < pages[i].width) canvas.width = pages[i].width;
        canvas.height = canvas.height + pages[i].height;
        context.putImageData(pages[i], 0, start);
        start += pages[i].height;
    }
    });

所以,从我的方式来看,这应该有用,对吧?
当我运行这个时,我最终得到的画布很大,包含pdf的所有页面但不显示pdf …

感谢您的帮助.

解决方法:

我不能说你的代码中将pdf渲染成画布的部分,但我确实看到了一些问题.

>每次重置canvas.width或canvas.height都会自动清除画布内容.因此,在顶部,不需要clearRect,因为画布在每个pages.render之前被canvas.width清除.
>更重要的是,在底部,所有以前的pdf绘图都会被每个画布大小调整(oops!).
> getImageData()获取一个数组,其中每个像素由该数组的4个连续元素表示(红色然后是绿色,然后是蓝色,然后是alpha).因为getImageData()是一个数组,所以它没有pages [i] .width或pages [i] .height-它只有一个pages [i] .length.该阵列长度不能用于确定宽度或高度.

因此,为了让您入门,我首先将您的代码更改为此(非常非常未经测试!):

var pdf = null;
PDFJS.disableWorker = true;
var pages = new Array();
//Prepare some things
var canvas = document.getElementById('cv');
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) {
    pdf = _pdf;
    //Render all the pages on a single canvas
    for(var i = 1; i <= pdf.numPages; i ++){
        pdf.getPage(i).then(function getPage(page){
            var viewport = page.getViewport(scale);
            // changing canvas.width and/or canvas.height auto-clears the canvas
            canvas.width = viewport.width;
            canvas.height = viewport.height;
            page.render({canvasContext: context, viewport: viewport});
            pages[i-1] = context.getImageData(0, 0, canvas.width, canvas.height);
            // calculate the width of the final display canvas
            if(canvas.width>maxCanvasWidth){
              maxCanvasWidth=canvas.width;
            }
            // calculate the accumulated with of the final display canvas
            canvasHeight+=canvas.height;
            // save the "Y" starting position of this pages[i]
            pageStarts[i]=pageStarts[i-1]+canvas.height;
            p.Out("pre-rendered page " + i);
        });
    }


    canvas.width=canvasWidth; 
    canvas.height = canvasHeight;  // this auto-clears all canvas contents
    for(var i = 0; i < pages.length; i++){
        context.putImageData(pages[i], 0, pageStarts[i]);
    }

});

或者,这是一种更传统的完成任务的方式:

使用单个“显示”画布,允许用户“翻阅”每个所需页面.

由于您已经开始将每个页面绘制到画布中,为什么不为每个页面保留单独的隐藏画布.然后,当用户想要查看第6页时,您只需将隐藏的画布#6复制到显示画布上.

Mozilla开发人员在他们的pdfJS演示中使用这种方法:http://mozilla.github.com/pdf.js/web/viewer.html

您可以在此处查看查看器的代码:http://mozilla.github.com/pdf.js/web/viewer.js

标签:pdf-js,javascript,html5-canvas,getimagedata,putimagedata
来源: https://codeday.me/bug/20190930/1835004.html