Skip to content

Commit

Permalink
fix scaling and display high PDF in high resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
lfoppiano committed May 11, 2024
1 parent be53b47 commit 63d717b
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 22 deletions.
6 changes: 3 additions & 3 deletions streamlit_pdf_viewer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@


def pdf_viewer(input: Union[str, Path, bytes],
width: int = 700,
width: int = None,
height: int = None,
key=None,
annotations: list = (),
Expand Down Expand Up @@ -58,7 +58,7 @@ def pdf_viewer(input: Union[str, Path, bytes],
"""

# Validate width and height parameters
if not isinstance(width, int):
if width is not None and not isinstance(width, int):
raise TypeError("Width must be an integer")
if height is not None and not isinstance(height, int):
raise TypeError("Height must be an integer or None")
Expand Down Expand Up @@ -100,7 +100,7 @@ def pdf_viewer(input: Union[str, Path, bytes],

viewer = pdf_viewer(
binary,
height=700,
# height=700,
width=800,
annotations=annotations
)
84 changes: 65 additions & 19 deletions streamlit_pdf_viewer/frontend/src/PdfViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<div id="pdfContainer" :style="pdfContainerStyle">
<div v-if="args.rendering==='unwrap'">
<div id="pdfViewer" :style="pdfViewerStyle">
<!-- <div class="urlsAnnotations"></div>-->
<div id="pdfAnnotations" v-if="args.annotations">
<div v-for="(annotation, index) in filteredAnnotations" :key="index" :style="getPageStyle">
<div :style="getAnnotationStyle(annotation)" :id="`annotation-${index}`"></div>
Expand All @@ -26,6 +27,7 @@ import { onMounted, onUpdated, computed, ref} from "vue";
import "pdfjs-dist/build/pdf.worker.entry";
import {getDocument} from "pdfjs-dist/build/pdf";
import {Streamlit} from "streamlit-component-lib";
import PDFViewerApplicationOptions from "core-js/internals/task"
export default {
props: ["args"],
Expand All @@ -36,6 +38,17 @@ export default {
const pageScales = ref([]);
const pageHeights = ref([]);
// console.log("--- INIT ---")
// console.log("inner width: " + window.innerWidth)
// console.log("inner height: " + window.innerHeight)
// console.log("outer height: " + window.outerHeight)
// console.log("Width: " + maxWidth.value)
document.addEventListener('webviewerloaded', function () {
PDFViewerApplicationOptions.set('printResolution', 300);
});
const isRenderingAllPages = props.args.pages_to_render.length === 0;
const filteredAnnotations = computed(() => {
Expand Down Expand Up @@ -96,21 +109,35 @@ export default {
const createCanvasForPage = (page, scale, rotation, pageNumber) => {
const viewport = page.getViewport({scale, rotation});
// console.log(`Page viewport size: ${viewport.width}, ${viewport.height}`)
const ratio = window.devicePixelRatio || 1
const canvas = document.createElement("canvas");
canvas.id = `canvas_page_${pageNumber}`;
canvas.height = viewport.height;
canvas.width = viewport.width;
canvas.height = viewport.height * ratio;
canvas.width = viewport.width * ratio;
canvas.style.width = viewport.width + 'px';
canvas.style.height = viewport.height + 'px';
canvas.style.display = "block";
canvas.style.marginBottom = `${props.args.pages_vertical_spacing}px`;
canvas.getContext("2d").scale(ratio, ratio);
return canvas;
};
const renderPage = async (page, canvas) => {
const renderContext = {
canvasContext: canvas.getContext("2d"),
viewport: page.getViewport({scale: pageScales.value[page._pageIndex], rotation: page.rotate}),
viewport: page.getViewport({
scale: pageScales.value[page._pageIndex],
rotation: page.rotate,
intent: "print",
})
};
// console.log(`Scale page ${page._pageIndex}: ${pageScales.value[page._pageIndex]}`);
const renderTask = page.render(renderContext);
await renderTask.promise;
};
Expand All @@ -123,22 +150,41 @@ export default {
}
}
for (let i = 1; i <= pdf.numPages; i++) {
const page = await pdf.getPage(i);
const rotation = page.rotate;
const actualViewport = page.getViewport({scale: 1.0, rotation: rotation});
const scale = props.args.width / actualViewport.width;
pageScales.value.push(scale);
pageHeights.value.push(actualViewport.height);
if (pagesToRender.includes(i)) {
const canvas = createCanvasForPage(page, scale, rotation, i);
pdfViewer?.append(canvas);
if (canvas.width > maxWidth.value) {
maxWidth.value = canvas.width;
}
totalHeight.value += canvas.height;
totalHeight.value += props.args.pages_vertical_spacing;
await renderPage(page, canvas);
if (props.args.width === null || props.args.width === undefined) {
maxWidth.value = window.innerWidth
} else if (Number.isInteger(props.args.width)) {
maxWidth.value = props.args.width
// If the desired width is larger than the available inner width,
// we should not exceed it. To be revised
if (window.innerWidth < maxWidth.value) {
maxWidth.value = window.innerWidth
}
}
// const PRINT_UNITS = 300 / 72.0
console.log("Device pixel ratio" + window.devicePixelRatio)

Check warning on line 167 in streamlit_pdf_viewer/frontend/src/PdfViewer.vue

View workflow job for this annotation

GitHub Actions / build (3.10, 18)

Unexpected console statement

Check warning on line 167 in streamlit_pdf_viewer/frontend/src/PdfViewer.vue

View workflow job for this annotation

GitHub Actions / build (3.8, 20)

Unexpected console statement

Check warning on line 167 in streamlit_pdf_viewer/frontend/src/PdfViewer.vue

View workflow job for this annotation

GitHub Actions / build (3.8, 18)

Unexpected console statement

Check warning on line 167 in streamlit_pdf_viewer/frontend/src/PdfViewer.vue

View workflow job for this annotation

GitHub Actions / build (3.7, 20)

Unexpected console statement

Check warning on line 167 in streamlit_pdf_viewer/frontend/src/PdfViewer.vue

View workflow job for this annotation

GitHub Actions / build (3.12, 18)

Unexpected console statement

Check warning on line 167 in streamlit_pdf_viewer/frontend/src/PdfViewer.vue

View workflow job for this annotation

GitHub Actions / build (3.10, 20)

Unexpected console statement

Check warning on line 167 in streamlit_pdf_viewer/frontend/src/PdfViewer.vue

View workflow job for this annotation

GitHub Actions / build (3.9, 18)

Unexpected console statement

Check warning on line 167 in streamlit_pdf_viewer/frontend/src/PdfViewer.vue

View workflow job for this annotation

GitHub Actions / build (3.11, 18)

Unexpected console statement

Check warning on line 167 in streamlit_pdf_viewer/frontend/src/PdfViewer.vue

View workflow job for this annotation

GitHub Actions / build (3.7, 18)

Unexpected console statement
for (let pageNumber = 1; pageNumber <= pdf.numPages; pageNumber++) {
const page = await pdf.getPage(pageNumber)
const rotation = page.rotate
// Initial viewport
const unscaledViewport = page.getViewport({
scale: 1.0,
rotation: rotation,
})
const scale = maxWidth.value / unscaledViewport.width
// console.log(`Page scale: ${scale}`)
pageScales.value.push(scale)
pageHeights.value.push(unscaledViewport.height)
if (pagesToRender.includes(pageNumber)) {
const canvas = createCanvasForPage(page, scale, rotation, pageNumber)
pdfViewer?.append(canvas)
totalHeight.value += canvas.height
totalHeight.value += props.args.pages_vertical_spacing
await renderPage(page, canvas)
}
}
// Subtract the margin for the last page as it's not needed
Expand Down

0 comments on commit 63d717b

Please sign in to comment.