iPhone программно обрезает квадратное изображение, чтобы оно появилось в виде круга - PullRequest
12 голосов
/ 06 марта 2012

Я пытаюсь создать изображение для пользовательского стиля UIButton, используя изображение с камеры на iPhone.Кнопка имеет круглый фон и фактически выглядит как круг.Теперь мне нужно изображение, чтобы перейти в середину кнопки, которая также выглядит круглой.

Как вырезать квадратный UIImage, чтобы он выглядел круглым с прозрачностью за пределами круглой области?

Если используется маскирование, нужно ли предварительно отрисовывать маску или я могу создать ее программно(например, круг)?

Спасибо!

Ответы [ 10 ]

28 голосов
/ 06 марта 2012

Я никогда не делал ничего подобного, но попробуйте использовать QuartzCore framework и его свойство 'cornerRadius. Пример:

#import <QuartzCore/QuartzCore.h>
//some other code ...
UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
imgView.layer.cornerRadius = 10.0f;

поиграйте с этим немного, и вы получите то, что хотите.

Надеюсь, это поможет

13 голосов
/ 06 марта 2012

Да, вы можете использовать CoreGraphics для динамического рисования маски.Затем вы можете создать замаскированное изображение.

Пример для маскировки:

- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage
{
  CGImageRef maskRef = maskImage.CGImage;
  CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                      CGImageGetHeight(maskRef),
                                      CGImageGetBitsPerComponent(maskRef),
                                      CGImageGetBitsPerPixel(maskRef),
                                      CGImageGetBytesPerRow(maskRef),
                                      CGImageGetDataProvider(maskRef), NULL, false);

  CGImageRef maskedImageRef = CGImageCreateWithMask([image CGImage], mask);
  UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef];
  CGImageRelease(maskedImageRef);
  CGImageRelease(mask);
  return maskedImage;
}
7 голосов
/ 25 февраля 2013

Я начал изучать это пару недель назад.Я перепробовал все предложения здесь, ни одно из которых не сработало.По великой традиции RTFM я пошел и прочитал документацию Apple по Quartz 2D Programming и придумал это.Пожалуйста, попробуйте и дайте мне знать, как вы идете.

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

Убедитесь, что вы включилиQuartz 2D в вашем проекте.

#include <math.h>

+ (UIImage*)circularScaleNCrop:(UIImage*)image: (CGRect) rect{
    // This function returns a newImage, based on image, that has been:
    // - scaled to fit in (CGRect) rect
    // - and cropped within a circle of radius: rectWidth/2

    //Create the bitmap graphics context
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(rect.size.width, rect.size.height), NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    //Get the width and heights
    CGFloat imageWidth = image.size.width;
    CGFloat imageHeight = image.size.height;
    CGFloat rectWidth = rect.size.width;
    CGFloat rectHeight = rect.size.height;

    //Calculate the scale factor
    CGFloat scaleFactorX = rectWidth/imageWidth;
    CGFloat scaleFactorY = rectHeight/imageHeight;

    //Calculate the centre of the circle
    CGFloat imageCentreX = rectWidth/2;
    CGFloat imageCentreY = rectHeight/2;

    // Create and CLIP to a CIRCULAR Path
    // (This could be replaced with any closed path if you want a different shaped clip)
    CGFloat radius = rectWidth/2;
    CGContextBeginPath (context);
    CGContextAddArc (context, imageCentreX, imageCentreY, radius, 0, 2*M_PI, 0);
    CGContextClosePath (context);
    CGContextClip (context);

    //Set the SCALE factor for the graphics context
    //All future draw calls will be scaled by this factor
    CGContextScaleCTM (context, scaleFactorX, scaleFactorY);    

    // Draw the IMAGE
    CGRect myRect = CGRectMake(0, 0, imageWidth, imageHeight);
    [image drawInRect:myRect];

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

Включите следующий код в свой класс UIView, заменив "monk2.png" вашим собственным именем изображения.

- (void)drawRect:(CGRect)rect
{

    UIImage *originalImage = [UIImage imageNamed:[NSString stringWithFormat:@"monk2.png"]];
    CGFloat oImageWidth = originalImage.size.width;
    CGFloat oImageHeight = originalImage.size.height;
    // Draw the original image at the origin
    CGRect oRect = CGRectMake(0, 0, oImageWidth, oImageHeight);
    [originalImage drawInRect:oRect];

    // Set the newRect to half the size of the original image 
    CGRect newRect = CGRectMake(0, 0, oImageWidth/2, oImageHeight/2);
    UIImage *newImage = [self circularScaleNCrop:originalImage :newRect];

    CGFloat nImageWidth = newImage.size.width;
    CGFloat nImageHeight = newImage.size.height;

    //Draw the scaled and cropped image
    CGRect thisRect = CGRectMake(oImageWidth+10, 0, nImageWidth, nImageHeight);
    [newImage drawInRect:thisRect];

}
6 голосов
/ 18 февраля 2014
{
    imageView.layer.cornerRadius =  imageView.frame.size.height /2;
    imageView.layer.masksToBounds = YES;
    imageView.layer.borderWidth = 0;
}
6 голосов
/ 08 февраля 2014

Вот быстрый способ создать закругленные углы на квадратном ImageView, чтобы он выглядел как идеальный круг.В основном вы применяете угловой радиус, равный 1/2 ширины (ширина == высота на квадратном изображении).

#import <QuartzCore/QuartzCore.h> //you need QuartzCore
...

float width = imageView.bounds.size.width;  // we can also use the frame property instead of bounds since we just care about the Size and don't care about position
imageView.layer.cornerRadius = width/2;
5 голосов
/ 10 июля 2013

UIImage категория для маскировки изображения с кружком:

UIImage *originalImage = [UIImage imageNamed:@"myimage.png"];
UImage *myRoundedImage = [UIImage roundedImageWithImage:originalImage];

Получите здесь .

2 голосов
/ 23 марта 2013

У меня есть другое решение:

- (UIImage *)roundedImageWithRect:(CGRect)rect radius:(CGFloat)radius
{
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, rect.size.width, rect.size.height) cornerRadius:radius];

CGFloat imageRatio = self.size.width / self.size.height;
CGSize imageSize = CGSizeMake(rect.size.height * imageRatio, rect.size.height);
CGRect imageRect = CGRectMake(0, 0, imageSize.width, imageSize.height);

[path addClip];
[self drawInRect:imageRect];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return image;

}

Этот вариант лучше для производительности, чем прямая установка cornerRadius.

0 голосов
/ 18 апреля 2014

Просто используйте

_profilePictureImgView.layer.cornerRadius = 32.0f;
_profilePictureImgView.layer.masksToBounds = YES;  
0 голосов
/ 30 мая 2012

Ниже приводится ответ, который я дал в Как обрезать UIImage по овальной или круглой форме? , чтобы сделать изображение кругом. У меня это работает ..

Загрузить файл архива поддержки

#import "UIImage+RoundedCorner.h"
#import "UIImage+Resize.h"

Следующие строки используются для изменения размера изображения и преобразования в округленный радиус

UIImage *mask = [UIImage imageNamed:@"mask.jpg"];

mask = [mask resizedImage:CGSizeMake(47, 47) interpolationQuality:kCGInterpolationHigh ];
mask = [mask roundedCornerImage:23.5 borderSize:1];
0 голосов
/ 06 марта 2012

Лично я бы создал изображение прозрачного круга с непрозрачными углами для наложения фотографии. Это решение подходит только в тех случаях, когда вы будете размещать изображение в одном месте интерфейса пользователя, и предполагается, что непрозрачные углы будут сливаться с фоном.

...