我在 React 中使用画布,并使用画布将 pdf 渲染为图像。
现在,当我获得新数据,即添加另一个 pdf 时,然后 再次必须使用画布。
我不确定如何修复此错误或如何删除画布,甚至在再次使用画布之前清除画布。
相关代码如下:
pdfLoop = (item,index) => {
var that = this;
PDFJS.getDocument(item).then(function getPdfHelloWorld(pdf) {
//
// Fetch the first page
console.log('url is : ',item);
pdf.getPage(1).then(function getPageHelloWorld(page) {
var scale = 0.5;
var viewport = page.getViewport(scale);
let cref = 'canvas'+index;
let imgref ='img'+index;
console.log('cref no : ',cref);
console.log('img no : ',imgref);
// Prepare canvas using PDF page dimensions
//
var canvas = that.canvasRefs[cref];
//let imagez = that.imageRefs[imgref];
var context = canvas.getContext('2d');
context.globalcompositeoperation = 'source-over';
// context.fillStyle = "#fff";
//draw on entire canvas
//context.fillRect( 0, 0, canvas.width, canvas.height );
canvas.height = viewport.height;
canvas.width = viewport.width;
//imagez.src = canvas.toDataURL("image/png");
//
// Render PDF page into canvas context
//
//page.render({canvasContext: context, viewport: viewport});
var task = page.render({canvasContext: context, viewport: viewport})
task.promise.then(function(){
//console.log(canvas.toDataURL('image/png'));
let imgItem = {imgref:canvas.toDataURL('image/png'),page:index+1,rotate:0}
let newState = that.state.imgsrc;
newState[index] = imgItem;
//let newState = that.state.imgsrc.concat(imgItem);
that.setState({
imgsrc:newState
});
//imagez.src = canvas.toDataURL('image/png')
});
});
});
}
如果有人偶然发现此问题,错误消息将显示以下内容
Use different canvas or ensure previous operations were cancelled or completed.
获取文件时,如果已有文件,则必须将其销毁。即:
PDFJS.getDocument({ url: pdf_url }).promise
.then((pdf_doc) => {
if (this.pdf_doc) {
this.pdf_doc.destroy();
}
this.pdf_doc = pdf_doc;
this.total_pages = this.pdf_doc.numPages;
})
我不知道这是否是一个好的解决方案,但至少它对我有用。
在某些情况下,当 pdf 具有操作按钮(例如下一个/上一个或缩放)时,会显示此错误。 在这种情况下,通常您有一个渲染 pdf 页面的功能,例如:
renderPage(num) {
// Using promise to fetch the page
pdfDoc.getPage(num).then(function (page) {
const viewport = page.getViewport({scale: scale});
canvas.height = viewport.height;
canvas.width = viewport.width;
// Render PDF page into canvas context
const renderContext = {
canvasContext: ctx,
viewport: viewport
};
page.render(renderContext);
});
}
要修复错误,只需执行以下更改:
添加两个变量用于控制冲突和缓存等待页数:
pageRendering = false; // Check conflict
pageNumPending = null; // Cache waiting page number
按如下方式使用这些变量:
renderPage(num) {
if (this.pageRendering) { // Check if other page is rendering
this.pageNumPending = num; // Cache waited page number until previous page rendering completed
} else {
this.pageRendering = true;
// Using promise to fetch the page
pdfDoc.getPage(num).then(function (page) {
const viewport = page.getViewport({scale: scale});
canvas.height = viewport.height;
canvas.width = viewport.width;
// Render PDF page into canvas context
const renderContext = {
canvasContext: ctx,
viewport: viewport
};
const renderTask = page.render(renderContext);
// Wait for rendering to finish
renderTask.promise.then(function () {
this.pageRendering = false;
if (pageNumPending !== null) {
// Waited page must be rendered
this.renderPage(pageNumPending);
// Must be set to null to prevent infinite loop
this.pageNumPending = null;
}
});
});
我在使用 PDF.js 时遇到了完全相同的问题,解决方案是, 渲染完成后,您必须清除context。
if (context) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
}
这将确保上下文被清除并为下一次渲染做好准备,并且错误消失。
这对我有用。
我遇到了和你一样的问题,但我的解决方案与之前发布的答案有点不同。
对我来说,问题在于我“不必要地通过状态更改重新渲染”。检查您是否在没有正确清除画布的情况下没有重新渲染组件,或者您是否甚至需要重新渲染(在我的例子中我不需要)。 希望这能有所帮助
<div id="div_canvas">
<canvas id="cnv"></canvas>
</div>
然后,在调用 pdf.js 函数之前,删除“div_canvas”内容并重新创建它:
$("#div_canvas").html("");
$("#div_canvas").html("<canvas id='cnv'></canvas>");
isPageRendering = false;
pageQueue = [];
self = this;
renderPage(num, canvas) {
if (self.isPageRendering) // Check if a given page is already rendering...
self.pageQueue.push(num); // Enqueue page number until previous page rendering completed
else {
self.isPageRendering = true;
// Using promise to fetch the page
pdfDoc.getPage(num).then(function (page) {
if (!canvas)
canvas = $(`.pdf-canvas${num}`)[0];
//debugger;
var viewport = page.getViewport({ scale: self.scale, rotation: self.rotation[num - 1] });
canvas.height = viewport.height;
canvas.width = viewport.width;
var ctx = canvas.getContext('2d');
// Render PDF page into canvas context
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
const renderTask = page.render(renderContext);
renderTask.promise.then(function () {
//debugger;
//console.log('Canvas data: ' + canvas.toDataURL()); // debugging
self.isPageRendering = false;
if (self.pageQueue.length > 0)
self.renderPage(self.pageQueue.pop()); // recursive call to renderPage to render the remaining pages
});
});
}
}