picta para mockup inc idraw apps app iphone graphics

para - iphone vector png



¿Cómo enmascarar una imagen cuadrada en una imagen con esquinas redondeadas en el iPhone SDK? (8)

¿Cómo se puede enmascarar una imagen cuadrada en una imagen con esquinas redondeadas?


Ambos métodos funcionan, pero las diferencias aparecen según dónde lo uses.

Por ejemplo: si tiene una vista de tabla con las celdas que muestran una imagen junto con otras etiquetas, etc., y usa layer para establecer el rincón de esquina, el desplazamiento tendrá un gran éxito. Se pone desigual.

Me enfrenté a este problema cuando estaba usando Layer para una imagen en una celda de vista de tabla y estaba tratando de descubrir la causa de ese espasmo solo para descubrir que CALayer era el culpable.

Usó la primera solución de hacer las cosas en drawRect explicado por NilObject. Eso funciona como un encanto con el desplazamiento siendo liso como la seda.

Por otro lado, si desea utilizar esto en vistas estáticas como la vista de popover, etc., la capa es la forma más fácil de hacerlo.

Como dije, ambos métodos funcionan bien, solo que debes decidir en función de dónde quieras usarlos.


Aquí hay un método aún más fácil que está disponible en iPhone 3.0 y posteriores. Cada objeto basado en la vista tiene una capa asociada. Cada capa puede tener un radio de esquina establecido, esto le dará exactamente lo que quiere:

UIImageView * roundedView = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"wood.jpg"]]; // Get the Layer of any view CALayer * layer = [roundedView layer]; [layer setMasksToBounds:YES]; [layer setCornerRadius:10.0]; // You can even add a border [layer setBorderWidth:4.0]; [layer setBorderColor:[[UIColor blueColor] CGColor]];

Para utilizar estos métodos, es posible que deba agregar:

#import <QuartzCore/QuartzCore.h>


Me doy cuenta de que esto es una noticia antigua, pero solo para reducirlo un poco:

Aquí hay dos posibles preguntas: (1) cómo aplico esquinas redondeadas a una UIView (como UIImageView), que se mostrará en pantalla, y (2) cómo enmascaré una imagen cuadrada (es decir, un UIImage) ) para producir una nueva imagen con esquinas redondeadas.

Para (1), el curso más fácil es usar CoreAnimation y establecer la propiedad view.layer.cornerRadius

// Because we''re using CoreAnimation, we must include QuartzCore.h // and link QuartzCore.framework in a build phases #import <QuartzCore/QuartzCore.h> // start with an image UIImage * fooImage = [UIImage imageNamed:@"foo.png"]; // put it in a UIImageView UIView * view = [UIImageView alloc] initWithImage:fooImage]; // round its corners. This mask now applies to the view''s layer''s *background* view.layer.cornerRadius = 10.f // enable masksToBounds, so the mask applies to its foreground, the image view.layer.masksToBounds = YES;

Para (2), la mejor manera es usar las operaciones de gráficos de UIKit:

// start with an image UIImage * fooImage = [UIImage imageNamed:@"foo.png"]; CGRect imageRect = CGRectMake(0, 0, fooImage.size.width, fooImage.size.height); // set the implicit graphics context ("canvas") to a bitmap context for images UIGraphicsBeginImageContextWithOptions(imageRect.size,NO,0.0); // create a bezier path defining rounded corners UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:imageRect cornerRadius:10.f]; // use this path for clipping in the implicit context [path addClip]; // draw the image into the implicit context [fooImage drawInRect:imageRect]; // save the clipped image from the implicit context into an image UIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext(); // cleanup UIGraphicsEndImageContext();

Lo complicado del problema (2) es que podrías pensar que podrías hacer toda la operación usando la propiedad view.layer.mask en CoreAnimation. Pero no se puede porque el método CALayer renderInContext: para generar un UIImage desde la capa enmascarada, parece ignorar la máscara. Peor aún, la documentación para renderInContext: no menciona esto, y solo alude al comportamiento de OSX 10.5.

Un poco más de contexto: el enfoque anterior de (2) es el uso de envoltorios UIKit alrededor de la funcionalidad CoreGraphics más básica. Puedes hacer lo mismo usando las llamadas de CoreGraphics directamente, eso es lo que está haciendo la respuesta elegida, pero luego necesitas construir la ruta de bezier rect redondeada manualmente desde curvas y líneas y también necesitas compensar el hecho de que CoreGraphics usa una sistema de coordenadas de dibujo que se voltea con respecto a UIKit.


Muy simple. self.profileImageView.layer.cornerRadius = self.profileImageView.frame.size.width / 2; self.profileImageView.clipsToBounds = SÍ;

Para cada vista, hay una propiedad de capa agrupada. Entonces, la primera línea de lo anterior es establecer el radio de esquina del objeto de capa (es decir, una instancia de clase CALayer). Para hacer una imagen circular a partir de una imagen cuadrada, el radio se establece en la mitad del ancho de UIImageView. Por ejemplo, si el ancho de la imagen al cuadrado es de 100 píxeles. El radio se establece en 50 píxeles. En segundo lugar, debe establecer la propiedad clipsToBounds en SÍ para que la capa funcione.


Partiendo de las algal , aquí hay un par de métodos que es bueno poner en una categoría de UIImage:

- (UIImage *) roundedCornerImageWithRadius:(CGFloat)radius { CGRect imageRect = CGRectMake(0, 0, self.size.width, self.size.height); UIGraphicsBeginImageContextWithOptions(imageRect.size,NO,0.0); //scale 0 yields better results //create a bezier path defining rounded corners and use it for clippping UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:imageRect cornerRadius:radius]; [path addClip]; // draw the image into the implicit context [self drawInRect:imageRect]; // get image and cleanup UIImage *roundedCornerImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return roundedCornerImage; } + (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size andCornerRadius:(CGFloat)radius { UIImage *image = nil; if (size.width == 0 || size.height == 0) { size = CGSizeMake(1.0, 1.0); } CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height); UIGraphicsBeginImageContextWithOptions(rect.size,NO,0.0); //yields sharper results than UIGraphicsBeginImageContext(rect.size) CGContextRef context = UIGraphicsGetCurrentContext(); if (context) { CGContextSetFillColorWithColor(context, [color CGColor]); if (radius > 0.0) { //create a bezier path defining rounded corners and use it for clippping UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius]; [path addClip]; CGContextAddPath(context, path.CGPath); } CGContextFillRect(context, rect); image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } return image; }


Puede usar CoreGraphics para crear una ruta para un rectángulo redondo con este fragmento de código:

static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight) { float fw, fh; if (ovalWidth == 0 || ovalHeight == 0) { CGContextAddRect(context, rect); return; } CGContextSaveGState(context); CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect)); CGContextScaleCTM (context, ovalWidth, ovalHeight); fw = CGRectGetWidth (rect) / ovalWidth; fh = CGRectGetHeight (rect) / ovalHeight; CGContextMoveToPoint(context, fw, fh/2); CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); CGContextClosePath(context); CGContextRestoreGState(context); }

Y luego llame a CGContextClip (context); para acortarlo a la ruta del rectángulo. Ahora cualquier dibujo realizado, incluido el dibujo de una imagen, se recortará en la forma del rectángulo redondo.

Como ejemplo, suponiendo que "imagen" es un UIImage, y esto está en un método drawRect:

CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); addRoundedRectToPath(context, self.frame, 10, 10); CGContextClip(context); [image drawInRect:self.frame]; CGContextRestoreGState(context);



Yo uso este método

+ (UIImage *)imageWithColor:(UIColor *)color andSize:(CGSize)size; { UIImage *img = nil; CGRect rect = CGRectMake(0, 0, size.width, size.height); UIGraphicsBeginImageContext(rect.size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, color.CGColor); CGContextFillRect(context, rect); img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return img; }