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