Dado un UIImage de cualquier dimensión, deseo para generar un "icono" cuadrado versión en tamaño, px
píxeles a un lado, sin ninguna distorsión (estiramiento). Sin embargo, me encuentro con un pequeño inconveniente. No estoy seguro de dónde está el problema. Esto es lo que estoy haciendo hasta ahora.El uso apropiado de UIRectClip para escalar un UIImage hacia abajo para el tamaño del icono
En primer lugar, dado un uImagesize
, puedo determinar tres cosas: la ratio
de usar cuando se escala por la imagen; un delta
(la diferencia entre nuestro tamaño deseado icono y el lado más largo), y un offset
(que se utiliza para averiguar nuestro origen de coordenadas al recortar la imagen):
if (size.width > size.height) {
ratio = px/size.width;
delta = (ratio*size.width - ratio*size.height);
offset = CGPointMake(delta/2, 0);
} else {
ratio = px/size.height;
delta = (ratio*size.height - ratio*size.width);
offset = CGPointMake(0, delta/2);
}
Ahora, supongamos que usted tiene una imagen 640px de ancho por 480px de alto, y queremos obtener un ícono de 50px x 50px de esto. La anchura es mayor que la altura, por lo que nuestros cálculos son:
ratio = 50px/640px = 0.078125
delta = (ratio * 640px) - (ratio * 480px) = 50px - 37.5px = 12.5px
offset = {x=6.25, y=0}
A continuación, se crea un CGRectrect
que es lo suficientemente grande como para ser cultivada hasta nuestro tamaño del icono deseado sin distorsión, además de un clipRect
de recorte propósitos:
CGRect rect = CGRectMake(0.0, 0.0, (ratio * size.width) + delta,
(ratio * size.height) + delta);
CGRect clipRect = CGRectMake(offset.x, offset.y, px, px);
Sustituyendo nuestros valores desde arriba, obtenemos:
rect = origin {x=0.0, y=0.0}, size {width=62.5, height=50.0}
clipRect = origin {x=6.25, y=0}, size {width=50.0, height=50.0}
Ahora tenemos un rect alto de 62.5px de ancho por 50px, y un rectángulo de recorte que agarra la porción "media" de 50x50.
¡En la recta final! A continuación, configuramos nuestro contexto de imagen, dibuje el UIImage (llamado myImage
aquí) en la rect, establezca el rectángulo de recorte, obtenga la imagen (presumiblemente recortada), úselo y finalmente limpie nuestro contexto de imagen:
UIGraphicsBeginImageContext(rect.size);
[myImage drawInRect:rect];
UIRectClip(clipRect);
UIImage *icon = UIGraphicsGetImageFromCurrentImageContext();
// Do something with the icon here ...
UIGraphicsEndImageContext();
Un solo problema: ¡el recorte nunca ocurre! Termino con una imagen de 63 px de ancho x 50 px de alto. :(
Quizás estoy haciendo un mal uso/malentendido UIRectClip? He intentado barajar varias cosas: cambiar el uso de rect
y clipRect
, moviendo UIRectClip antes de drawInRect:. No dados.
Traté de buscar un ejemplo de este método en línea también, en vano. Para el registro, UIRectClip se define como:
modifica la trayectoria actual de recorte por intersección con la especificada rectángulo.
Barajar las cosas no nos lleva un poco más cerca:
UIGraphicsBeginImageContext(clipRect.size);
UIRectClip(rect);
[myImage drawInRect:rect];
Ahora que no tienen distorsión, pero la imagen recortada no está centrada en el original como lo esperaba.Aún así, al menos la imagen es de 50x50, aunque los nombres de las variables ahora están sucios como resultado de dicha mezcla. (Respetuosamente dejaré el cambio de nombre como un ejercicio para el lector.)
Gracias por compartir esto! Ha pasado un tiempo desde que miré con lo que terminé. Definitivamente no quería ni pretendo ninguna distorsión usando mi método. Tu "cuadro más grande posible" suena sensato, y estoy muy feliz de escuchar que UIRectClip no es necesario. (¡Otros lectores, pesen y vean cómo esto también vuela para ustedes!) –
Gracias, específicamente por la frase "Además, no es necesario usar UIClipRect - si se hace el contexto del tamaño de la imagen que desea extraer, no se hará ningún dibujo real fuera de ese rect de todos modos " – xaphod