0

I have a boundingBox selecting a zone in a image and i would like to scale this boundingBox to my canvas ratio.

I would like to recalculate the ratio of my boundingBox to correctly target a zone of the resized image in the canvas.

Here an example + jsFiddle : ( this is an example, the real project use multiple boundingBox with a big range of images)``

The boundingBox coordinate / width and height are calculated from the image but after the transformation i dont know how to convert the coordinate / ratio.

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext("2d");

//bbox  
let [bx, by, bw, bh] = [146, 58, 82, 87]

console.log(bx, by, bw, bh)

function bboxDraw(){
    // Draw the bounding box.
  ctx.strokeStyle = "#00FFFF";
  ctx.lineWidth = 4;
  ctx.strokeRect(bx, by, bw, 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)
}

JSFiddle

Any good idea to preserve the ratio after the scale2fill transformation and correctly target the boundingBox area ?

Spok Human
  • 21
  • 5
  • I think you want `scaleToFit` in https://stackoverflow.com/a/38898699/3877726 LOL Amazing how code travels out in the wild and comes back with some erroneous baggage, the signs of new forgotten abilities, and never managed to modernize along the way.. – Blindman67 Sep 24 '20 at 16:32
  • The question is about the boundingBox not the scaleToFill/Fit function to handle the image. I found the solution. I need to use the real width/height of the image to recalculate the coordinates of the boundingBox using percent. – Spok Human Sep 26 '20 at 16:51
  • The bounding box is given in `scaleToFir` when the Image is rendered with width as `img.width * scale`, and height as `img.height * scale` – Blindman67 Sep 26 '20 at 16:56

1 Answers1

0

To recalculate BoundingBox coordinates from image after scale to fill transformation in HTML Canvas.

We need to recalculate the width/height/x/y of the boundingBox using the naturalWidth and naturalHeight of the image.

 
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";
}

Updated JSFiddle

Spok Human
  • 21
  • 5