Jak zamaskować kwadratowy obraz w obrazie z okrągłymi rogami w systemie iOS?

Jak zamaskować kwadratowy obraz w obraz z okrągłymi rogami?

Author: Cœur, 2009-06-15

8 answers

Możesz użyć CoreGraphics, aby utworzyć ścieżkę dla okrągłego prostokąta za pomocą tego fragmentu kodu:

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);
}

A następnie wywołaj CGContextClip( context);, aby przyciąć go do ścieżki prostokąta. Teraz każdy wykonany rysunek, w tym rysunek obrazu, zostanie przycięty do okrągłego prostokąta.

Na przykład, zakładając, że "image" jest UIImage, a to jest w drawrect: method:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
addRoundedRectToPath(context, self.frame, 10, 10);
CGContextClip(context);
[image drawInRect:self.frame];
CGContextRestoreGState(context);
 67
Author: NilObject,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-24 19:46:30

Oto jeszcze łatwiejsza metoda, która jest dostępna w iPhone 3.0 i nowszych. Każdy obiekt oparty na widoku ma powiązaną warstwę. Każda warstwa może mieć ustawiony promień narożnika, to da ci to, czego chcesz:

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]];

Aby użyć tych metod, może być konieczne dodanie:

#import <QuartzCore/QuartzCore.h>
 35
Author: MagicSeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-24 11:51:34

Zdaję sobie sprawę, że to stara wiadomość, ale żeby się trochę zagotować:

Istnieją dwa możliwe pytania: (1) Jak zastosować zaokrąglone rogi do widoku UIView (takiego jak UIImageView), który będzie wyświetlany na ekranie, oraz (2) jak zamaskować kwadratowy obraz (czyli UIImage), aby utworzyć nowy obraz z zaokrąglonymi rogami.

Dla (1) najprostszym sposobem jest użycie CoreAnimation i ustawienie widoku.warstwa.cornerRadius property

 // 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;

Dla (2), najlepszym sposobem jest użycie Operacje graficzne 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();

Trudne w problemie (2) jest to, że możesz pomyśleć, że możesz wykonać całą operację za pomocą widoku.warstwa.właściwości maski w CoreAnimation. Ale nie możesz, ponieważ metoda CALayer renderInContext:, której używasz do generowania interfejsu użytkownika z zamaskowanej warstwy, wydaje się ignorować maskę. Co gorsza, dokumentacja renderInContext: nie wspomina o tym, a jedynie nawiązuje do zachowania OSX 10.5.

Jakiś dalszy kontekst: powyższe podejście do (2) wykorzystuje UIKit obejmuje bardziej podstawową funkcjonalność CoreGraphics. Możesz zrobić to samo, używając wywołań CoreGraphics bezpośrednio – to robi wybrana odpowiedź - ale następnie musisz ręcznie zbudować zaokrągloną ścieżkę rect Beziera z krzywych i linii, a także musisz zrekompensować fakt, że CoreGraphics używa układu współrzędnych rysunku, który jest odwrócony względem UIKit.

 16
Author: algal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-11 22:12:13

Zobacz ten Post - bardzo prosta odpowiedź

Jak ustawić zaokrąglone rogi w obrazach interfejsu użytkownika w iPhonie

UIImageView * roundedView = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"wood.jpg"]];
// Get the Layer of any view
CALayer * l = [roundedView layer];
[l setMasksToBounds:YES];
[l setCornerRadius:10.0];
 2
Author: GAL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:25:45

Bardzo proste. siebie.profileImageView.warstwa.cornerRadius = self.profileImageView.rama.rozmiar.szerokość / 2; siebie.profileImageView.clipsToBounds = YES;

Dla każdego widoku istnieje właściwość warstwy wiązanej. Tak więc pierwszą linią powyższego jest ustawienie promienia narożnika obiektu layer (tj. instancji klasy CALayer). Aby utworzyć okrągły obraz z kwadratowego obrazu, promień jest ustawiony na połowę szerokości interfejsu UIImageView. Na przykład, jeśli szerokość kwadratu obrazu wynosi 100 pikseli. Promień jest ustawiony na 50 pikseli. Po drugie, musisz ustawić właściwość clipsToBounds na Yes, aby warstwa działała.

 1
Author: Shahab Qureshi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-08 07:50:17

Obie metody działają, ale różnice pojawiają się w zależności od tego, gdzie ich używasz.

Dla Ex: jeśli masz widok tabeli z komórkami pokazującymi obraz wraz z innymi etykietami itp., i użyć warstwy, aby ustawić cornerRadius, przewijanie zajmie duży hit. Robi się sucho.

Miałem do czynienia z tym problemem, gdy używałem warstwy jako obrazu w komórce widoku tabeli i starałem się ustalić przyczynę tego szarpnięcia, tylko po to, aby dowiedzieć się, że winowajcą był CALayer.

Pierwsze rozwiązanie robienia rzeczy w drawRect wyjaśnione przez NilObject. To działa jak urok, a przewijanie jest gładkie jak jedwab.

Z drugiej strony, jeśli chcesz użyć tego w statycznych widokach, takich jak widok popover itp., warstwa jest najprostszym sposobem, aby to zrobić.

Jak powiedziałem, obie metody działają dobrze tylko, że trzeba zdecydować na podstawie, gdzie chcesz go użyć.

 0
Author: Deepak G M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-17 09:13:33

Używam tej metody.

+ (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;
    }
 0
Author: Voda Ion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-24 14:39:40

Budowanie z algal , Oto kilka metod, które warto umieścić w kategorii 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;
}
 0
Author: n8tr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:25:45