Подтвердить что ты не робот

Как замаскировать квадратное изображение в изображение с закругленными углами в iOS?

Как вы можете замаскировать квадратное изображение в изображение с круглыми углами?

4b9b3361

Ответ 1

Вы можете использовать CoreGraphics для создания пути для круглого прямоугольника с помощью этого фрагмента кода:

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

И затем вызовите CGContextClip (контекст); чтобы скопировать его в прямоугольник. Теперь любой чертеж, включая рисование изображения, будет привязан к круглой форме прямоугольника.

В качестве примера, предполагая, что "образ" является UIImage, и это находится в методе drawRect::

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

Ответ 2

Вот еще более простой метод, доступный в iPhone 3.0 и выше. Каждый объект, основанный на представлении, имеет связанный уровень. На каждом слое может быть установлен радиус угла, это даст вам именно то, что вы хотите:

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

Чтобы использовать эти методы, вам может потребоваться добавить:

#import <QuartzCore/QuartzCore.h>

Ответ 3

Я понимаю, что это старые новости, но просто немного кипеть:

Здесь есть два возможных вопроса: (1) как применить закругленные углы к UIView (например, UIImageView), которые будут отображаться на экране, и (2) как я могу скрыть квадратное изображение (то есть, UIImage) для создания нового изображения с закругленными углами.

Для (1) проще всего использовать CoreAnimation и установить свойство 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 layer *background*
 view.layer.cornerRadius = 10.f
 // enable masksToBounds, so the mask applies to its foreground, the image
 view.layer.masksToBounds = YES;

Для (2) наилучшим способом является использование графических операций 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();

Какая сложность в проблеме (2) заключается в том, что вы можете подумать, что можете выполнить всю операцию, используя свойство view.layer.mask в CoreAnimation. Но вы не можете, потому что метод CALayer renderInContext:, который вы использовали для создания UIImage из маскированного слоя, кажется, игнорирует маску. Хуже того, документация для renderInContext: не упоминает об этом и ссылается только на поведение OSX 10.5.

Следующий контекст: вышеприведенный подход к (2) использует обертки UIKit вокруг более основных функций CoreGraphics. Вы можете сделать то же самое, используя прямые вызовы CoreGraphics - это то, что делает выбранный ответ, - но тогда вам нужно построить закругленный прямой bezier-путь вручную из кривых и линий, и вам также необходимо компенсировать тот факт, что CoreGraphics использует рисование системы координат, которая перевернута относительно UIKit's.

Ответ 5

Очень просто.   self.profileImageView.layer.cornerRadius = self.profileImageView.frame.size.width/2;   self.profileImageView.clipsToBounds = YES;

Для каждого представления существует свойство связанного слоя. Таким образом, первая строка приведена выше, чтобы задать угловой радиус объекта слоя (то есть экземпляр класса CALayer). Чтобы сделать круговое изображение из квадрата изображения, радиус устанавливается на половину ширины UIImageView. Например, если ширина квадрата изображения составляет 100 пикселей. Радиус установлен в 50 пикселей. Во-вторых, вы должны установить для свойства clipsToBounds значение YES, чтобы заставить слой работать.

Ответ 6

Оба метода работают, но различия проявляются в зависимости от того, где вы его используете.

Для примера: если у вас есть представление таблицы с ячейками, показывающими изображение вместе с другими метками и т.д., и вы используете слой для установки cornerRadius, прокрутка сильно пострадает. Он дергается.

Я столкнулся с этой проблемой, когда я использовал Layer для изображения в ячейке таблицы и пытался выяснить причину этой ярости только для того, чтобы найти, что CALayer был виновником.

Использовалось первое решение по использованию материала в drawRect, которое объясняется NilObject. Это работает как шарм с прокруткой, гладкой, как шелк.

С другой стороны, если вы хотите использовать это в статических представлениях, таких как popover view и т.д., слой - это самый простой способ сделать это.

Как я уже сказал, оба метода хорошо работают, так что вам нужно решить, на основе того, где вы хотите его использовать.

Ответ 7

Я использую этот метод.

+ (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;
    }

Ответ 8

Сборка algal, вот несколько методов, которые приятно включить в категорию 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;
}