mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-01-20 07:16:10 +01:00
🐛 Fix PDF rectangle annotation screenshot rotation handling https://ld246.com/article/1766895521854 (#16714)
Fix screenshot position and orientation errors when page is rotated, properly handle the combination of user rotation and PDF's own rotation
This commit is contained in:
parent
df86253231
commit
58afc27c39
1 changed files with 58 additions and 29 deletions
|
|
@ -762,43 +762,72 @@ const copyAnno = (idPath: string, fileName: string, pdf: any) => {
|
|||
}, Constants.TIMEOUT_DBLCLICK);
|
||||
};
|
||||
|
||||
const getCaptureCanvas = async (pdfObj: any, pageNumber: number) => {
|
||||
const pdfPage = await pdfObj.pdfDocument.getPage(pageNumber);
|
||||
const viewport = pdfPage.getViewport({scale: 1.5 * pdfObj.pdfViewer.currentScale * window.pdfjsLib.PixelsPerInch.PDF_TO_CSS_UNITS});
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = Math.floor(viewport.width);
|
||||
canvas.height = Math.floor(viewport.height);
|
||||
|
||||
await pdfPage.render({
|
||||
canvasContext: canvas.getContext("2d"),
|
||||
viewport: viewport
|
||||
}).promise;
|
||||
|
||||
return canvas;
|
||||
};
|
||||
|
||||
async function getRectImgData(pdfObj: any) {
|
||||
const pageElement = hasClosestByClassName(rectElement, "page");
|
||||
if (!pageElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
const captureCanvas = await getCaptureCanvas(pdfObj, parseInt(pageElement.getAttribute("data-page-number")));
|
||||
const pageNumber = parseInt(pageElement.getAttribute("data-page-number"));
|
||||
const pageView = pdfObj.pdfViewer.getPageView(pageNumber - 1);
|
||||
if (!pageView) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rectStyle = (rectElement.firstElementChild as HTMLElement).style;
|
||||
const scale = 1.5;
|
||||
const captureImageData = captureCanvas.getContext("2d").getImageData(
|
||||
scale * parseFloat(rectStyle.left),
|
||||
scale * parseFloat(rectStyle.top),
|
||||
scale * parseFloat(rectStyle.width),
|
||||
scale * parseFloat(rectStyle.height));
|
||||
// PDF 截图时的缩放倍数,用于提高截图清晰度
|
||||
const CAPTURE_SCALE_RATIO = 1.5;
|
||||
|
||||
const tempCanvas = document.createElement("canvas");
|
||||
tempCanvas.width = captureImageData.width;
|
||||
tempCanvas.height = captureImageData.height;
|
||||
const ctx = tempCanvas.getContext("2d");
|
||||
ctx.putImageData(captureImageData, 0, 0);
|
||||
return tempCanvas.toDataURL();
|
||||
const pdfPage = await pdfObj.pdfDocument.getPage(pageNumber);
|
||||
const displayViewport = pageView.viewport.clone({rotation: 0});
|
||||
// displayViewport.scale 等于以前用的 pdfObj.pdfViewer.currentScale * window.pdfjsLib.PixelsPerInch.PDF_TO_CSS_UNITS
|
||||
const captureViewport = pdfPage.getViewport({scale: displayViewport.scale * CAPTURE_SCALE_RATIO, rotation: 0});
|
||||
const captureCanvas = document.createElement("canvas");
|
||||
captureCanvas.width = Math.floor(captureViewport.width);
|
||||
captureCanvas.height = Math.floor(captureViewport.height);
|
||||
|
||||
const captureCtx = captureCanvas.getContext("2d");
|
||||
await pdfPage.render({
|
||||
canvasContext: captureCtx,
|
||||
viewport: captureViewport
|
||||
}).promise;
|
||||
|
||||
const firstChild = rectElement.firstElementChild as HTMLElement;
|
||||
if (!firstChild) {
|
||||
return;
|
||||
}
|
||||
const rectStyle = firstChild.style;
|
||||
const captureImageData = captureCtx.getImageData(
|
||||
CAPTURE_SCALE_RATIO * parseFloat(rectStyle.left),
|
||||
CAPTURE_SCALE_RATIO * parseFloat(rectStyle.top),
|
||||
CAPTURE_SCALE_RATIO * parseFloat(rectStyle.width),
|
||||
CAPTURE_SCALE_RATIO * parseFloat(rectStyle.height)
|
||||
);
|
||||
|
||||
const resultCanvas = document.createElement("canvas");
|
||||
resultCanvas.width = captureImageData.width;
|
||||
resultCanvas.height = captureImageData.height;
|
||||
// 页面实际旋转角度 = 用户旋转 + PDF 本身旋转
|
||||
const totalRotation = (pageView.rotation + pageView.pdfPageRotate) % 360;
|
||||
const resultCtx = resultCanvas.getContext("2d");
|
||||
if (totalRotation === 0) {
|
||||
resultCtx.putImageData(captureImageData, 0, 0);
|
||||
} else {
|
||||
// 交换宽高
|
||||
if (totalRotation === 90 || totalRotation === 270) {
|
||||
[resultCanvas.width, resultCanvas.height] = [resultCanvas.height, resultCanvas.width];
|
||||
}
|
||||
resultCtx.translate(resultCanvas.width / 2, resultCanvas.height / 2);
|
||||
resultCtx.rotate((totalRotation * Math.PI) / 180);
|
||||
// 在旋转后的画布坐标系上绘制图片
|
||||
const tempCanvas = document.createElement("canvas");
|
||||
tempCanvas.width = captureImageData.width;
|
||||
tempCanvas.height = captureImageData.height;
|
||||
const tempCtx = tempCanvas.getContext("2d");
|
||||
tempCtx.putImageData(captureImageData, 0, 0);
|
||||
resultCtx.drawImage(tempCanvas, -tempCanvas.width / 2, -tempCanvas.height / 2);
|
||||
}
|
||||
|
||||
return resultCanvas.toDataURL();
|
||||
}
|
||||
|
||||
const setConfig = (pdf: any, id: string, data: IPdfAnno) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue