es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Obteniendo los valores de anchura y altura más rectangulares que puedan encajar una gran cantidad de píxeles en una imagen.

Cuál es la mejor manera de calcular el tamaño necesario para ajustar una matriz de píxeles en una imagen lo más cerca posible a una forma rectangular/cuadrada sin perder o agregar píxeles innecesarios?

Usando una imagen de 100 píxeles como ejemplo, el mejor tamaño para ajustar todos los píxeles sería 10×10, porque 10*10 es 100, es decir, agrega la menor cantidad de píxeles adicionales (en este caso 0). 100×1 también ajusta todos los píxeles, pero definitivamente es mucho menos rectangular que 10×10.

Y para ajustar 101 píxeles, el mejor tamaño es 8×13, aunque 8*13 es 104, es la única multiplicación que no pierde ningún píxel, agrega unos pocos píxeles adicionales (3) y tiene la forma más rectangular.

Hasta ahora he podido resolver este problema con las siguientes reglas:

  • Dividir el ancho entre el alto debe dar un valor mayor a 0.5 y menor a 1.5. (Esto garantiza que solo se mantengan los valores más rectangulares).
  • Multiplicar el ancho por el alto debe dar un valor mayor o igual al número de píxeles.

Al aplicar estas reglas, obtengo una variedad de posibilidades, siendo la mejor aquella que, al multiplicar, se acerca más al número de píxeles.

Esto es cómo se ve mi código actual:

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) // debe retornar [[8, 13], 3] (ancho, alto y píxeles adicionales)

Lo que hace es mantener una variable que guarda el menor resultado de (ancho*alto)-píxeles, que es la diferencia entre los valores encontrados y el número de píxeles.

Aunque funciona bien para cantidades pequeñas de píxeles, con valores enormes (que probablemente devolverían tamaños de 1000×1000), es extremadamente lento.

¿Hay alguna razón específica para esta lentitud? ¿Y sería posible obtener el mismo resultado sin usar bucles anidados?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Como modelo de lenguaje de IA, no puedo determinar la razón específica de la lentitud de tu código. Sin embargo, esto podría ser debido a la gran cantidad de iteraciones realizadas por los bucles for anidados. Para optimizar tu código, puedes intentar usar la técnica de búsqueda binaria, la cual reduce la cantidad de iteraciones necesarias.

    Por ejemplo, puedes buscar los valores de ancho y alto que mejor aproximen la cantidad de píxeles dividiendo iterativamente el espacio de búsqueda por la mitad. Esta técnica eliminará la necesidad de bucles for anidados y mejorará la complejidad temporal de tu código.

    Además, puedes considerar el uso de una fórmula matemática que calcule el tamaño necesario para ajustar un conjunto de píxeles en una imagen lo más cercano posible a una forma de rectángulo/cuadrado sin perder ni agregar píxeles innecesarios. Este enfoque será más rápido, ya que solo implica resolver una ecuación en lugar de iterar a través de un espacio de posibles soluciones.

    En resumen, puedes optimizar tu código explorando algoritmos alternativos que reduzcan la complejidad computacional, como la búsqueda binaria o fórmulas matemáticas.

Comments are closed.