2009-03-06 19 views
7

delimitación Por ejemplo, si necesito para llenar un cuadro delimitador que es 100px de ancho por 50px, las siguientes imágenes de entrada de altura tendría el siguiente comportamiento:escala para llenar por completo la caja

  1. 200w x 200h consigue reducido un 50% y 25% se corta desde la parte superior y abajo.

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

  3. 100w x 200h obtiene no tiene escala, pero 75px se corta 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á la respuesta en cualquier idioma, incluido el pseudo código. ¡Un enlace a una página con la respuesta también es genial!

+0

Alguien dejó un comentario en mi respuesta, pensé que era usted, pero no lo es, ¿puedes aclarar un poco la pregunta con respecto a tus limitaciones reales? Gracias. –

+0

El caso general es lo que yo quería. Gracias. – Larsenal

+0

Gracias. He editado la mitad engañosa de mi respuesta. –

Respuesta

12

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 su tamaño de entrada por la escala, y recorte el que salga 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 
+0

Solo la X (ancho) tiene restricciones de redimensionamiento. La otra Y (altura) está recortando. – Suroot

+0

Esa restricción no fue establecida, ni fue evidente por sus ejemplos. En ese caso, use scale = maxwidth/oldwidth en su lugar y elimine los cálculos cropleft/cropright, el resto permanece igual. –

+0

¿Deberíamos redondear los números de salida ya que a menudo son fracciones de un píxel? –

1

Aquí nos aseguramos de que solo escalemos si X es mayor que 100%; luego, una vez que hayamos hecho eso, nos aseguraremos de que tengamos solo 50 px en nuestra Y. Si somos mayores de 50, tomamos la diferencia y lo dividimos entre 2 para obtener la cantidad eliminada 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; 
} 
0

En gran parte inspirado por la respuesta de Mark Ransom (muchas gracias - me has salvado). Para cualquier persona que le gustaría hacer esto sin recortar la imagen (solo encajar 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 }; 
Cuestiones relacionadas