¿Cómo puedo cambiar el tamaño de una imagen a un ancho y alto específicos sin dejar de mantener su relación de aspecto? Estoy buscando ideas de algoritmos.

Es probable que haya una forma mucho más elegante de hacer esto, pero lo que siempre he hecho es algo así:

1) Supongamos que availableWidth y availableHeight definen el área de destino (fija) contra la que cambia el tamaño.

2) Supongamos que imageWidth e imageHeight representan el ancho y la altura ACTUAL de su imagen cargada en cualquier momento dado.

3) Primero, realice un cambio de tamaño restringido a la relación de aspecto bloqueado con el valor del Ancho disponible. Esto se hace ajustando primero la altura de la imagen cargada, luego configurando el ancho:

imageHeight = imageHeight x ( disponibleWidth / imageWidth)
imageWidth = availableWidth

4) El paso anterior supone que la imagen está orientada al paisaje (por lo tanto, utiliza el ancho como valor de bloqueo), pero puede que no lo sea, por lo que hacemos una comprobación rápida para ver si la altura de la imagen excede nuestra altura objetivo:

if ( imageHeight > availableHeight )

5) Si este es el caso, aplicamos el paso 3 nuevamente, pero esta vez usamos la altura como el valor de bloqueo:

imageWidth = imageWidth x (availableHeight / imageHeight)
imageHeight = altura disponible

6) En este punto, sabemos que tenemos una imagen que se ajusta al área delimitadora que hemos definido, por lo que es solo una cuestión de centrarla vertical y horizontalmente dentro de esa área, lo que se logra mediante una simple división y resta.

Siempre he tenido la impresión de que hay algún tipo de fórmula o algoritmo que combina los pasos de ancho y alto anteriores, pero cada vez que me veo obligado a hacer esto, tengo demasiado tiempo para darlo investigación adecuada 🙂

En lugar de tratar de adivinar y hacer un mal trabajo, pregúntele al usuario.

Tan pronto como el usuario cargue la foto, pregúnteles cómo quieren que se recorte la imagen. Muéstreles la misma foto, superpuesta con un borde de recorte de la relación de aspecto correcta. Permítales cambiar el tamaño del borde de recorte (sin cambiar la relación de aspecto). Una vez que confirman, utilízalo para recortar.

Esto se puede hacer fácilmente usando javascript. (Igal Alkon sugiere usar Jcrop: http://deepliquid.com/content/Jc …)

(Actualizaciones para responder basadas en los comentarios a continuación)

Este enfoque se puede combinar con cualquiera de los otros enfoques sugeridos para la heurística de recorte automático, por lo que adivina un cultivo y luego lo muestra al usuario para su confirmación.

En caso de que tenga varias fotos, puede mostrar una página intermedia con todas las fotos y los cultivos adivinados, y permitirles cambiar cualquiera que tenga un mal cultivo. La esperanza es que, en la mayoría de los casos, solo echen un vistazo a la página y hagan clic en Aceptar porque los cultivos adivinados estarían bien en la mayoría de los casos. De vez en cuando pueden modificar uno o dos de los cultivos. (Excepto por algunos usuarios quisquillosos que ajustarán el recorte para cada foto; y a estos usuarios les encantará esta función).

Este es un muy buen algoritmo para redimensionar y escalar proporcionalmente su imagen a cierta altura y ancho máximos

Cómo obtener nuestro divisor matemáticamente

supongamos que nuestra imagen original tiene ancho xy altura y;

x = 300 e y = 700

La altura máxima y el ancho máximo es 200;

primero, comprobaremos qué dimensión de la imagen es mayor que la otra.

Nuestra altura (y) es mayor que el ancho (x)

En segundo lugar, verificamos si nuestra altura es mayor que nuestra altura máxima.

Para nuestro caso, nuestra altura es mayor que la altura máxima. En un caso donde es menor que la altura máxima, establecemos nuestra nueva altura a nuestra altura original.

Finalmente, buscamos nuestro divisor como se muestra a continuación

si y se establece en la altura máxima 200

y = 200, es decir

si 700 = 200

qué pasa

300 =?

nuevo ancho = (200 (nueva altura) * 300 (ancho)) / 700 (alto)

entonces nuestro divisor es

divisor = nueva altura (300) / altura (700)

nuevo ancho = divisor * ancho o ancho / (1 / divisor)

Mira una demostración funcional desde aquí