Tengo un código que cambia el tamaño de una imagen para poder obtener un fragmento escalado del centro de la imagen. Utilizo esto para tomar UIImage
y devolver una pequeña representación cuadrada de una imagen, similar a lo que se ve en la vista del álbum de la aplicación Fotos. (Sé que podría usar UIImageView
ay ajustar el modo de recorte para lograr los mismos resultados, pero estas imágenes a veces se muestran en UIWebViews
).
Empecé a notar algunos bloqueos en este código y estoy un poco perplejo. Tengo dos teorías diferentes y me pregunto si alguna de ellas está en la base.
Teoría 1) Logro el recorte dibujando en un contexto de imagen fuera de pantalla de mi tamaño objetivo. Como quiero la parte central de la imagen, configuro el CGRect
argumento pasado drawInRect
a algo que es más grande que los límites del contexto de mi imagen. Esperaba que esto fuera kosher, pero ¿estoy tratando de dibujar otro recuerdo que no debería tocar?
Teoría 2) Estoy haciendo todo esto en un hilo de fondo. Sé que hay partes de UIKit que están restringidas al hilo principal. Supuse / esperaba que dibujar en una vista fuera de pantalla no fuera uno de estos. ¿Me equivoco?
(Oh, cómo extraño el NSImage's drawInRect:fromRect:operation:fraction:
método)
Respuestas:
Actualización 28/05/2014: escribí esto cuando iOS 3 más o menos era lo más nuevo, estoy seguro de que hay mejores formas de hacerlo por ahora, posiblemente incorporado. Como muchas personas han mencionado, este método no tiene en cuenta la rotación; lea algunas respuestas adicionales y difunda un poco de amor a favor para mantener las respuestas a esta pregunta útiles para todos.
Respuesta original:
Copiaré / pegaré mi respuesta a la misma pregunta en otro lugar:
No hay un método de clase simple para hacer esto, pero hay una función que puedes usar para obtener los resultados deseados:
CGImageCreateWithImageInRect(CGImageRef, CGRect)
te ayudará.Aquí hay un breve ejemplo usándolo:
fuente
imageOrientation
se establece en todo menos arriba,CGImage
se gira con respecto alUIImage
y el rectángulo de recorte estará equivocado. Puede rotar el rectángulo de recorte en consecuencia, pero el recién creadoUIImage
tendráimageOrientation
hacia arriba, de modo que el recortadoCGImage
se rotará dentro de él.[UIImage imageWithCGImage:imageRef scale:largeImage.scale orientation:largeImage.imageOrientation];
Para recortar imágenes de retina manteniendo la misma escala y orientación, use el siguiente método en una categoría UIImage (iOS 4.0 y superior):
fuente
self.scale
, ¿no?CGImageRelease(imageRef);
con ARC habilitado?Puede crear una categoría UIImage y usarla donde lo necesite. Basado en la respuesta de HitScans y los comentarios a continuación.
Puedes usarlo de esta manera:
fuente
[[UIScreen mainScreen] scale]
soloself.scale
? La escala de la imagen puede no ser la misma que la escala de la pantalla.No visible @interface for 'UIImage' declares the selector 'crop'
a pesar de que puse los archivos de categoría .h y .m en mi proyecto e importé el .h en la clase en la que estoy usando la categoría. ¿Alguna idea?Versión Swift 3
con ayuda de esta función de puente
CGRectMake
->CGRect
(créditos a esta respuesta respondida por@rob mayoff
):El uso es:
Salida:
fuente
guard
la primera línea en caso deUIImage.CGImage
devolucionesnil
y por qué usarvar
cuandolet
funciona perfectamente.cropping(to:)
mucho cuidado. El resultadoCGImage
tiene una fuerte referencia al más grandeCGImage
del que se recortó. Por lo tanto, si solo desea conservar la imagen recortada y no necesita el original, eche un vistazo a las otras soluciones.right
entonces el CGImage debe ser CCW girado 90 grados, de ahí el rect cultivo debe ser girado demasiadoAquí está mi implementación de recorte UIImage que obedece a la propiedad imageOrientation. Todas las orientaciones fueron probadas a fondo.
fuente
implicit declaration of function 'rad' is invalid in c99
puede eliminarse reemplazando: rad (90), rad (-90), rad (-180) -> M_PI_2, -M_PI_2, -_M_PIcontains undefined reference for architecture armv7
¿Me estoy perdiendo una biblioteca? CoreGraphics es importado.CGImage
Aviso : todas estas respuestas suponen un objeto de imagen respaldado.image.CGImage
puede devolver nil, siUIImage
está respaldado por aCIImage
, que sería el caso si creara esta imagen usando unCIFilter
.En ese caso, es posible que tenga que dibujar la imagen en un nuevo contexto y devolver esa imagen ( lento ).
fuente
Ninguna de las respuestas aquí maneja todos los problemas de escala y rotación 100% correctamente. Aquí hay una síntesis de todo lo dicho hasta ahora, actualizado a partir de iOS7 / 8. Está destinado a ser incluido como método en una categoría en UIImage.
fuente
Versión rápida de
awolf
la respuesta de, que funcionó para mí:fuente
La mayoría de las respuestas que he visto solo tratan con una posición de (0, 0) para (x, y). Ok, ese es un caso, pero me gustaría que mi operación de recorte esté centrada. Lo que me llevó un tiempo entender es la línea que sigue al comentario de WTF.
Tomemos el caso de una imagen capturada con orientación vertical:
Espero que tenga sentido! Si no es así, intente con diferentes valores, verá que la lógica se invierte cuando se trata de elegir la x, y, la anchura y la altura correctas para su cropRect.
fuente
swift3
fuente
Extensión rápida
fuente
La mejor solución para recortar un UIImage en Swift , en términos de precisión, escala de píxeles ...:
Instrucciones utilizadas para llamar a esta función:
Nota: la inspiración inicial del código fuente escrita en Objective-C se ha encontrado en el blog "Cocoanetics".
fuente
Debajo del fragmento de código podría ayudar.
fuente
Parece un poco extraño pero funciona muy bien y tiene en cuenta la orientación de la imagen:
fuente
Swift 5:
fuente
fuente
fuente
En iOS9.2SDK, uso el siguiente método para convertir el marco de UIView a UIImage
fuente
Actualización Swift 2.0 (
CIImage
compatibilidad)Se expande a partir de la Respuesta de Maxim, pero también funciona si su imagen está
CIImage
basada.fuente
Aquí hay una versión actualizada de Swift 3 basada en la respuesta de Noodles
fuente
Siga la respuesta de @Arne. Solo estoy arreglando la función Categoría. ponlo en la Categoría de UIImage.
fuente
No estaba satisfecho con otras soluciones porque toman varias veces (usando más potencia de la necesaria) o tienen problemas con la orientación. Esto es lo que usé para una imagen recortada cuadrada a escala de una imagen UIImage *.
fuente
Yo uso el siguiente método.
}
fuente
Mirar https://github.com/vvbogdan/BVCropPhoto
fuente