我有一个 Chrome 扩展程序,允许用户从屏幕的选定区域截取屏幕截图。
流程是这样的:
问题: 当用户选择要裁剪的区域时,最终结果会按比例放大并向左和向上移动一点。对于我的生活,我无法弄清楚为什么。此外,如果我尝试在垂直/水平滚动页面时进行裁剪,则会在顶部创建画布。我不确定这是否是相关问题。
下面的代码只是内容脚本的修改版本,没有服务器调用。
let selectableCanvasArea: HTMLCanvasElement;
let screenshotUrl: string;
let startX: number, startY: number, endX: number, endY: number;
export const startScreenshotProcess = (screenshotUrlParam: string): void => {
screenshotUrl = screenshotUrlParam; // This comes from the background script
createCanvas();
// Change the cursor
document.body.style.cursor = "crosshair";
// Darken the entire screen so we can see the cursor
document.body.style.filter = "brightness(50%)";
window.addEventListener("mousedown", mouseDownListener);
window.addEventListener("mouseup", mouseUpListener);
}
const createCanvas = () => {
// Create the canvas and prepend it to the HTML
selectableCanvasArea = document.createElement("canvas");
selectableCanvasArea.style.position = "absolute";
selectableCanvasArea.style.top = "0px";
selectableCanvasArea.style.left = "0px";
selectableCanvasArea.width = 0;
selectableCanvasArea.height = 0;
selectableCanvasArea.style.zIndex = "9999";
selectableCanvasArea.style.border = "3px dashed lightblue";
document.body.insertAdjacentElement('beforebegin', selectableCanvasArea);
}
const mouseDownListener = (e: MouseEvent): void => {
startX = e.clientX;
startY = e.clientY;
selectableCanvasArea.style.top = startY + "px";
selectableCanvasArea.style.left = startX + "px";
window.addEventListener("mousemove", mouseMoveListener);
}
const mouseMoveListener = (e: MouseEvent): void => {
e.preventDefault();
selectableCanvasArea.width = Math.abs(e.clientX - startX);
selectableCanvasArea.height = Math.abs(e.clientY - startY);
}
const mouseUpListener = (e: MouseEvent): void => {
endX = e.clientX;
endY = e.clientY;
processScreenshot();
}
export const processScreenshot = async () => {
const image = new Image();
image.src = screenshotUrl;
image.onload = () => {
let pos = selectableCanvasArea.getBoundingClientRect();
let originalX = (pos.left + window.scrollX);
let originalY = (pos.top + window.scrollY);
let croppedWidth = pos.width;
let croppedHeight = pos.height;
let croppedCanvas = document.createElement("canvas");
croppedCanvas.width = croppedWidth;
croppedCanvas.height = croppedHeight;
let ratioX = image.naturalWidth / croppedWidth;
let ratioY = image.naturalHeight / croppedHeight;
let context = croppedCanvas.getContext("2d");
context?.drawImage(image,
originalX, originalY, // sx, sy
croppedWidth, croppedHeight, // sWidth, sHeight
0, 0, // dx, dy
croppedWidth, croppedHeight // dWidth, dHeight
);
document.body.insertAdjacentHTML('beforebegin', `<img src="${croppedCanvas.toDataURL()}" alt="Cropped Image"/>`);
}
}
我的问题是 Chrome 截取的屏幕截图 与您的屏幕/标签的分辨率不同。
Ex:如果屏幕是 2000px 宽,图像可能是 1000px 宽。所以我们需要我们的起点和宽度为 1000/2000 (0.5)。
我用这段代码更新了上面的代码:
/* We need a ratio because the screenshot image is NOT the same resolution
as the screen that we see. Ex: If the screen is 2000px wide, the image might be 1000px wide. So we need our start points and width to be 1000/2000 (0.5) */
let ratio = image.width / window.innerWidth;
context?.drawImage(image,
(startX) * ratio,
(startY) * ratio,
(endX - startX) * ratio, (endY - startY) * ratio,
0, 0,
endX - startX, endY - startY);