Mi código funciona bien para dispositivos normales pero crea imágenes borrosas en dispositivos de retina.
¿Alguien sabe una solución para mi problema?
+ (UIImage *) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContext(view.bounds.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Respuestas:
Cambiar del uso de
UIGraphicsBeginImageContext
aUIGraphicsBeginImageContextWithOptions
(como se documenta en esta página ). Pase 0.0 para la escala (el tercer argumento) y obtendrá un contexto con un factor de escala igual al de la pantalla.UIGraphicsBeginImageContext
usa un factor de escala fijo de 1.0, por lo que en realidad obtienes exactamente la misma imagen en un iPhone 4 que en los otros iPhones. Apuesto a que el iPhone 4 está aplicando un filtro cuando lo escalas implícitamente o simplemente tu cerebro está notando que es menos agudo que todo lo que lo rodea.Entonces, supongo:
Y en Swift 4:
fuente
#import <QuartzCore/QuartzCore.h>
para eliminar larenderInContext:
advertencia.UIImage
recarga pero forzar la versión de alta resolución (y es probable que encuentres problemas debido a la menor RAM disponible en pre -redes dispositivos de todos modos).0.0f
parámetro para la escala, si es más aceptable de usar[[UIScreen mainScreen] scale]
, también funciona.scale: The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.
Está explícitamente documentado, por lo que 0.0f es más simple y mejor en mi opinión.La respuesta actualmente aceptada está desactualizada, al menos si es compatible con iOS 7.
Esto es lo que debe usar si solo es compatible con iOS7 +:
Swift 4:
Según este artículo , puede ver que el nuevo método iOS7
drawViewHierarchyInRect:afterScreenUpdates:
es muchas veces más rápido querenderInContext:
.fuente
drawViewHierarchyInRect:afterScreenUpdates:
es mucho más rápido. Acabo de ejecutar un generador de perfiles de tiempo en instrumentos. Mi generación de imágenes pasó de 138ms a 27ms.afterScreenUpdates:
aYES
?viewDidLoad
oviewWillAppear:
las imágenes son negras; Tuve que hacerlo adentroviewDidAppear:
. Así que finalmente volví arenderInContext:
.He creado una extensión Swift basada en la solución @Dima:
EDITAR: Swift 4 versión mejorada
Uso:
fuente
class
función que tiene una vista?static
función, pero como no hay necesidad de anularlo, simplemente puede cambiarlo a unastatic
función en lugar de hacerloclass
.Usando UIGraphicsImageRenderer moderno
fuente
renderer
con el viejodrawHierarchy
...?Para mejorar las respuestas de @Tommy y @Dima, use la siguiente categoría para representar UIView en UIImage con fondo transparente y sin pérdida de calidad. Trabajando en iOS7. (O simplemente reutilice ese método en la implementación, reemplazando
self
referencia con su imagen)UIView + RenderViewToImage.h
UIView + RenderViewToImage.m
fuente
@interface
y@implementation
ambos(RenderViewToImage)
y agregar#import "UIView+RenderViewToImage.h"
al encabezado, ¿ViewController.h
es este el uso correcto? por ejemploUIImageView *test = [[UIImageView alloc] initWithImage:[self imageByRenderingView]]; [self addSubview:test];
?ViewController.m
fue la vista que traté de representar- (UIView *)testView { UIView *v1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 50, 50)]; v1.backgroundColor = [UIColor redColor]; UIView *v2 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 150, 150)]; v2.backgroundColor = [UIColor blueColor]; [v2 addSubview:v1]; return v2; }
Swift 3
La solución Swift 3 (basada en la respuesta de Dima ) con la extensión UIView debería ser así:
fuente
Extensión Swift 3.0 incorporada que admite la nueva API iOS 10.0 y el método anterior.
Nota:
!
que podría causar un bloqueo.fuente
Swift 2.0:
Usando el método de extensión:
Uso:
fuente
Implementación Swift 3.0
fuente
Todas las respuestas de Swift 3 no funcionaron para mí, así que traduje la respuesta más aceptada:
fuente
Aquí hay una extensión Swift 4 UIView basada en la respuesta de @Dima.
fuente
Para Swift 5.1 puede usar esta extensión:
fuente
https://nshipster.com/image-resizing/
Así que asegúrese de que el tamaño al que está pasando
UIGraphicsImageRenderer
son puntos, no píxeles.Si sus imágenes son más grandes de lo que espera, debe dividir su tamaño por el factor de escala.
fuente
Algunas veces el método drawRect genera problemas, así que obtuve estas respuestas más apropiadas. Usted también puede echarle un vistazo Capture UIImage de UIView atascado en el método DrawRect
fuente
fuente
En este método, simplemente pase un objeto de vista y devolverá un objeto UIImage.
fuente
Agregue esto al método a la categoría UIView
fuente