【问题标题】:How to rotate Pdf.js canvas output in SVG in HTML in Chrome?如何在 Chrome 的 HTML 中旋转 SVG 中的 Pdf.js 画布输出?
【发布时间】:2019-09-28 12:35:01
【问题描述】:

我正在开发一个 Web 应用程序,它的 HTML 用户界面在某些时候涉及 SVG 图形。该 SVG 的一部分会进行各种转换,例如旋转。

在转换后的 SVG 图形中,我现在需要显示一个 PDF 文件(第一页)。为此,我使用了一个<foreignObject> element,它包含一个带有<canvas> element 的HTML 正文,可以作为PDF.js library 的目标1

这是一个最小示例,其中包含一个带有旋转变换的<g> element<g> 元素包含一个用于比较的常规 SVG 矩形以及与 PDF.js 输出的上述构造:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.2.2/pdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.2.2/pdf.worker.min.js"></script>
</head>
<body>
<svg width="800" height="600">
<rect width="100%" height="100%" fill="rgb(186, 224, 255)"/>
<g transform="rotate(-30) translate(10, 20) scale(1.5)">
    <rect x="100px" y="50px" width="100px" height="80px" stroke="red" fill="none"/>
    <foreignObject x="150px" y="300px" width="200" height="150">
        <xhtml:body margin="0px" padding="0px" width="200px" height="150px" border="1px solid black">
            <canvas width="200" height="150" id="cnv"/>
        </xhtml:body>
    </foreignObject>
</g>
</svg>
<script type="text/javascript">
pdfjsLib.getDocument('https://en.wikipedia.org/api/rest_v1/page/pdf/Canvas_element').promise.then(function (pdf) {
    return pdf.getPage(1);
}).then(function (page) {
    var viewport = page.getViewport({
        scale: 1
    });
    var pdfCanvas = document.getElementById('cnv');
    pdfCanvas.width = viewport.width;
    pdfCanvas.height = viewport.height;
    var renderCtx = {
        canvasContext: pdfCanvas.getContext('2d'),
        viewport: viewport
    };
    page.render(renderCtx);
});

</script>
</body>
</html>

在 Firefox 66 中,这符合预期:

然而,在 Chrome 74 中,画布从 PDF 的第一页(而不是其左上角)显示一个看似任意的矩形,并且此输出也不会旋转:

有什么办法可以解决这个问题并旋转 PDF 以在 Chrome 中的 SVG 中显示?


1:不知何故,无论我查看什么资源,如何在 JavaScript 中呈现 PDF 的问题似乎总是导致了这个库。此外,根据我在the library's website 上阅读的内容,SVG 渲染器仍在进行中,因此无法在客户可以上传任意 PDF 内容的地方使用。

【问题讨论】:

  • 不管我希望通过这个问题在 StackOverflow 上找到可能的解决方法,我同时还在 PDF.js 项目站点上打开了一个关于这个问题的issue。跨度>

标签: html google-chrome svg html5-canvas pdfjs


【解决方案1】:

我已经遇到过类似的问题。可能是为了性能,在 chrome - canvas 中使用不是从 SVG 派生的隔离上下文。 您可以改用 img 并将 pdf 渲染到隐藏的画布上。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.2.2/pdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.2.2/pdf.worker.min.js"></script>
</head>
<body>

<canvas width="200" height="150" id="cnv" style="position:absolute;left:-10000px"></canvas>

<svg width="800" height="600">
<rect width="100%" height="100%" fill="rgb(186, 224, 255)"/>
<g transform="rotate(-30) translate(10, 20) scale(1.5)">
    <rect x="100px" y="50px" width="100px" height="80px" stroke="red" fill="none"/>
    <foreignObject x="150px" y="300px" width="200" height="150">
        <xhtml:body margin="0px" padding="0px" width="200px" height="150px" border="1px solid black">
            <img id="img" x="150px" y="300px" width="200" height="150"/>
        </xhtml:body>
    </foreignObject>
</g>
</svg>
<script type="text/javascript">
pdfjsLib.getDocument('https://en.wikipedia.org/api/rest_v1/page/pdf/Canvas_element').promise.then(function (pdf) {
    return pdf.getPage(1);
}).then(function (page) {
    var viewport = page.getViewport({
        scale: 1
    });
    var pdfCanvas = document.getElementById('cnv');
    pdfCanvas.width = viewport.width;
    pdfCanvas.height = viewport.height;
    var renderCtx = {
        canvasContext: pdfCanvas.getContext('2d'),
        viewport: viewport
    };
    page.render(renderCtx);
});

// wait for page rendered, just use some pdf.js callback
setTimeout(function(){
    const cnv = document.getElementById('cnv');
    document.getElementById('img').src = cnv.toDataURL("image/png");
}, 2000);

</script>
</body>
</html>

【讨论】:

  • 有意思,准备试试这个。不过,这似乎不会发生在任何&lt;canvas&gt; 身上;在寻找解决方案时,我还在画布而不是 PDF 中使用了一些非常简单的自定义绘制图形进行了快速测试,并且该示例即使在 Chrome 中也能正常工作。
  • 这行得通。这样做时,SVG 文档中的结构甚至会变得相当容易,因为不需要 &lt;foreignObject&gt; 的东西;在这种情况下,我可以直接使用 SVG &lt;image&gt;
猜你喜欢
  • 1970-01-01
  • 2022-10-23
  • 2017-12-15
  • 2012-04-05
  • 2020-07-11
  • 1970-01-01
  • 2017-08-06
  • 2016-01-12
  • 2016-04-23
相关资源
最近更新 更多