Pregunta

Por ejemplo, si necesito rellenar un cuadro delimitador que tenga un ancho de 100px por un alto de 50px, las siguientes imágenes de entrada tendrían el siguiente comportamiento:

  1. 200w x 200h se reduce un 50% y El 25% se corta de la parte superior y abajo.

  2. 200w x 100h se reduce un 50% sin recortar.

  3. 100w x 200h se obtiene no se escala, pero 75px se cortan en la parte superior e inferior.

Parece que sería una función de cambio de tamaño común, pero no he podido rastrear un ejemplo del algoritmo.

Aceptará respuesta en cualquier idioma, incluido el pseudo código. ¡Un enlace a una página con la respuesta también es genial!

¿Fue útil?

Solución

Lo que estás pidiendo es bastante fácil. Calcule los diferentes factores de escala para el ancho y la altura, luego elija el más grande para su factor de escala real. Multiplique el tamaño de su entrada por la escala y recorte lo que resulte demasiado grande.

scale = max(maxwidth/oldwidth, maxheight/oldheight)
scaledwidth = oldwidth * scale
scaledheight = oldheight * scale
if scaledheight > maxheight:
    croptop = (scaledheight - maxheight) / 2
    cropbottom = (scaledheight - maxheight) - croptop
if scaledwidth > maxwidth:
    cropleft = (scaledwidth - maxwidth) / 2
    cropright = (scaledwidth - maxwidth) - cropleft

Otros consejos

Aquí nos aseguramos de que solo escalamos si X es mayor que 100%; luego, después de hacer eso, nos aseguramos de que solo tenemos 50 px en nuestra Y. Si somos más de 50, tomamos la diferencia y dividimos por 2 para eliminar la cantidad de la parte superior / inferior.

double percent_x = 1.0;

if(X > 100) {
 percent_x = (float)100/X;
 X *= percent_x;
 Y *= percent_x;
}

int diff_y;
int top_cut, bott_cut;
if( Y > 50 ) {
 diff_y = (Y - 50) / 2;
 top_cut = bott_cut = diff_y;
}

En gran parte inspirado por la respuesta de Mark Ransom (muchas gracias, me salvaste). Para cualquier persona que quiera hacer esto sin recortar la imagen (solo quepa dentro de los límites), he encontrado que esto funciona:

if (maxWidth > width && maxHeight > height) {
  return { width, height };
}

aspectRatio = width / height,
scale       = max(maxWidth / width, maxHeight / height);

scaledHeight = height * scale,
scaledWidth  = width * scale;

if (scaledHeight > maxHeight) {
  scaledHeight = maxHeight;
  scaledWidth  = aspectRatio * scaledHeight;
} else if (scaledWidth > maxWidth) {
  scaledWidth  = maxWidth;
  scaledHeight = scaledWidth / aspectRatio;
}

return { scaledHeight, scaledWidth };
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top