问题描述
我有一个boundingBox选择图像中的一个区域,我想将此boundingBox缩放到我的画布比例。
我想重新计算我的boundingBox的比率,以正确定位画布中调整大小后的图像区域。
这里有一个例子+ jsfiddle:(这是一个例子,真实的项目使用具有大范围图像的多个boundingBox)''
boundingBox的坐标/宽度和高度是从图像中计算出来的,但是在转换之后,我不知道如何转换坐标/比率。
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext("2d");
//bBox
let [bx,by,bw,bh] = [146,58,82,87]
console.log(bx,bh)
function bBoxDraw(){
// Draw the bounding Box.
ctx.strokeStyle = "#00FFFF";
ctx.linewidth = 4;
ctx.strokeRect(bx,bh);
// Draw the label background.
ctx.fillStyle = "#00FFFF";
}
function scaletoFill(img,callback){
canvas.width = window.innerWidth
canvas.height = window.innerHeight
// get the scale
var scale = Math.max(canvas.width / img.width,canvas.height / img.height);
// get the top left position of the image
var x = (canvas.width / 2) - (img.width / 2) * scale;
var y = (canvas.height / 2) - (img.height / 2) * scale;
ctx.drawImage(img,x,y,img.width * scale,img.height * scale);
bBoxDraw()
}
let img = new Image()
try {
img.src = "https://via.placeholder.com/1280x720"
} catch (error) {
console.log("image URL",error);
}
img.onload = function() {
scaletoFill(this)
}
在scale2fill转换后保留比例并正确定位boundingBox区域的好主意吗?
解决方法
要在缩放后从图像重新计算BoundingBox坐标以填充HTML画布中的变换。
我们需要使用图像的naturalWidth和naturalHeight重新计算boundingBox的宽度/高度/ x / y。
let [bx,by,bw,bh] = [146,58,82,87]
function bboxRatioDraw(img) {
// Use percent to correctly adapt the coordinate to the scaled image
let percentBx = (100 * (bx / img.naturalWidth)),// x %
percentBy = (100 * (by / img.naturalHeight)),// y %
percentBw = (bw * 100) / img.naturalWidth,// width%
percentBh = (bh * 100) / img.naturalHeight; // height%
// then map the values to the current canvas
let finalBx = (percentBx * canvas.width) / 100,// x en pixel
finalBy = (percentBy * canvas.height) / 100,// y en pixel
finalBw = (percentBw * canvas.width) / 100,// width en pixel
finalBh = (percentBh * canvas.height) / 100; // height en pixel
// Draw the bounding box.
ctx.strokeStyle = "green";
ctx.lineWidth = 4;
ctx.strokeRect(finalBx,finalBy,finalBw,finalBh);
// Draw the label background.
ctx.fillStyle = "#00FFFF";
}