From 72b97453d3ac70bfdbe881059131fb96bb044042 Mon Sep 17 00:00:00 2001 From: 16337 <1633794139@qq.com> Date: Wed, 18 Mar 2026 16:30:33 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9AROI=20Canvas=20?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E5=BC=8F=E5=AF=B9=E9=BD=90=EF=BC=8C=E7=B2=BE?= =?UTF-8?q?=E7=A1=AE=E8=A6=86=E7=9B=96=E5=9B=BE=E7=89=87=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E5=8C=BA=E5=9F=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 通过计算 object-fit: contain 下图片的真实渲染区域,让 Canvas 精确覆盖 图片内容而非整个容器(含黑边),解决不同屏幕/缩放下 ROI 偏移问题。 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../aiot/device/roi/components/RoiCanvas.vue | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/apps/web-antd/src/views/aiot/device/roi/components/RoiCanvas.vue b/apps/web-antd/src/views/aiot/device/roi/components/RoiCanvas.vue index d41de2b27..1e4890149 100644 --- a/apps/web-antd/src/views/aiot/device/roi/components/RoiCanvas.vue +++ b/apps/web-antd/src/views/aiot/device/roi/components/RoiCanvas.vue @@ -90,12 +90,43 @@ function onImageError() { nextTick(() => initCanvas()); } +function getImageContentRect() { + const img = wrapper.value?.querySelector('img'); + if (!img || !img.naturalWidth || !wrapper.value) { + return { + x: 0, + y: 0, + w: wrapper.value?.clientWidth ?? 0, + h: wrapper.value?.clientHeight ?? 0, + }; + } + const cW = wrapper.value.clientWidth; + const cH = wrapper.value.clientHeight; + const imgRatio = img.naturalWidth / img.naturalHeight; + const cRatio = cW / cH; + let rW: number; + let rH: number; + if (imgRatio > cRatio) { + rW = cW; + rH = cW / imgRatio; + } else { + rH = cH; + rW = cH * imgRatio; + } + return { x: (cW - rW) / 2, y: (cH - rH) / 2, w: rW, h: rH }; +} + function initCanvas() { if (!canvas.value || !wrapper.value) return; - canvasWidth = wrapper.value.clientWidth; - canvasHeight = wrapper.value.clientHeight; + const rect = getImageContentRect(); + canvasWidth = rect.w; + canvasHeight = rect.h; canvas.value.width = canvasWidth; canvas.value.height = canvasHeight; + canvas.value.style.left = `${rect.x}px`; + canvas.value.style.top = `${rect.y}px`; + canvas.value.style.width = `${rect.w}px`; + canvas.value.style.height = `${rect.h}px`; ctx = canvas.value.getContext('2d'); redraw(); } @@ -365,10 +396,6 @@ function drawPolygonInProgress() { .roi-overlay { position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; cursor: crosshair; }