Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

159
Vistas
Getting the most rectangular width and height values ​that can fit a large amount of pixels in an image

What's the best way to calculate the size needed to fit an array of pixels into an image as close as possible to a rectangle/square shape without losing or adding unnecessary pixels?

Using an image of 100 pixels as an example, the best size to fit all pixels would be 10x10, because 10*10 is 100, that is, it adds the least amount of extra pixels (in this case 0). 100x1 also fits all pixels, but it sure is much less rectangular than 10x10.

And in order to fit 101 pixels the best size is 8x13, although 8*13 is 104, it's the only multiplication that doesn't lose any pixels, adds few extra pixels (3), and has the most rectangular shape.

So far I have been able to solve this problem with the following rules:

  • Dividing width by height must result in a value greater than 0.5 and less than 1.5. (This will ensure that only the most rectangular values ​​are kept).
  • Multiplying width by height must result in a value greater than or equal to the number of pixels.

By applying these rules I end up with a variety of possibilities, the best one being the one that, when multiplied, most closely approximates the number of pixels.

Here's what my code looks like currently:

function loopPixels(pixels, callback) {
    for (let x = 2; x < pixels; x++) {
        for (let y = 2; y < pixels; y++) {
            callback(x, y);
        }
    }
}

function getRectangle(pixels) {
    let result = {extraPixels: pixels};
    loopPixels(pixels, (left, right) => {
        let half = (left/right);
        let total = (left*right);

        if (Math.round(half) == 1 && total >= pixels) {
            if (total-pixels < result.extraPixels) {
                result = {size: [left, right], extraPixels: total-pixels}; 
            }
        }
    })
    return result;
}

getRectangle(101) // must return [[8, 13], 3] (width, height and additional pixels)

What it does is keep a variable holding the smallest result of (width*height)-pixels, which is the difference between the found values ​​and the number of pixels.

Although it works fine for small amounts of pixels, with huge values (which would likely return 1000x1000 sizes), it's ultra slow.

Is there a specific reason for such slowness? and would it be possible to get the same result without using nested for loops?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

The following code can be made more efficient but it is very descriptive. It takes a pixel count (n) and a k value which denotes the best k matches.

Lets try 68M pixels for some resonable aspect ratios.

function getReasonableDimensions(n,k){
  var max = ~~Math.sqrt(n);
  return Array.from({length: max}, (_,i,a) => [n%(max-i),max-i])
              .sort((a,b) => a[0] - b[0])
              .slice(0,k)
              .map(t => [Math.floor(n/t[1]), t[1]]);
}

var res = getReasonableDimensions(68000000,10)
console.log(JSON.stringify(res));

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda