Как я могу взять UIImage и дать ему черную рамку?

126

Как установить границу а UIImage?

фаэтон
источник
Случайно, если кто-то услышит поиск Google (как я) и хочет добавить границу в UIImageView, поищите ответ от @mclin внизу. Прекрасно работает!
Махендра Лия

Ответы:

241

С OS> 3.0 вы можете сделать это:

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

[imageView.layer setBorderColor: [[UIColor blackColor] CGColor]];
[imageView.layer setBorderWidth: 2.0];
mclin
источник
1
Когда я AspectFit изображения в приведенном выше imageView, изображение просматривается идеально, но стороны изображения остаются пустыми, и то же самое происходит с верхней и нижней частью изображения, когда изображение является альбомным. Пустое пространство выглядит некрасиво с установленной рамкой .. Сталкивались ли вы с этой проблемой? Если да, пожалуйста, предложите способ решения этой проблемы
Встречайте
@Hamutsi imageView.image = myImage;
Кайл Клегг
6
Да, ты можешь. Экземпляры UIImageмогут быть отображены в графическом контексте с помощью CoreGraphics.
Марк Адамс
Как указывает @rockstar, вам может потребоваться добавить imageView.layer.masksToBounds = YES;
Бьорн Рош
Эта ссылка была решением, которое я искал.
GrandSteph
67

Вы можете сделать это, создав новое изображение (также ответ на него вы найдете в другой публикации этого вопроса):

- (UIImage*)imageWithBorderFromImage:(UIImage*)source;
{
  CGSize size = [source size];
  UIGraphicsBeginImageContext(size);
  CGRect rect = CGRectMake(0, 0, size.width, size.height);
  [source drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0];

  CGContextRef context = UIGraphicsGetCurrentContext();
  CGContextSetRGBStrokeColor(context, 1.0, 0.5, 1.0, 1.0); 
  CGContextStrokeRect(context, rect);
  UIImage *testImg =  UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  return testImg;
}  

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

Маркус С. Зарра
источник
Как указать нужную ширину границы?
Патрик
16
CGContextSetLineWidth
Маркус С. Зарра
@ MarcusS.Zarra Я понимаю, что их не существовало, когда был дан ответ на этот вопрос, но это решение не принимает во внимание дисплей Retina. Если бы вы могли его отредактировать, я был бы очень благодарен :)
Люк
@lukech Образец в доработке не требуется. Просто увеличьте ширину линии, если вы используете устройство Retina.
Маркус С. Зарра
2
Это size320x480 независимо от того, используете вы устройство Retina или нет, поэтому при сохранении изображения оно сохраняется с разрешением 320x480 пикселей, а не 640x960.
Люк
38
#import <QuartzCore/CALayer.h>


UIImageView *imageView = [UIImageView alloc]init];
imageView.layer.masksToBounds = YES;
imageView.layer.borderColor = [UIColor blackColor].CGColor;
imageView.layer.borderWidth = 1;    

Этот код можно использовать для добавления UIImageViewграницы просмотра.

Файзан Рефаи
источник
идеальный! Нет необходимости мучиться с CGImage. (Мне не нужно было сохранять изображение с рамкой). Огромное спасибо!
Septronic 05
13
imageView_ProfileImage.layer.cornerRadius =10.0f;
imageView_ProfileImage.layer.borderColor = [[UIColor blackColor] CGColor];
imageView_ProfileImage.layer.borderWidth =.4f;
imageView_ProfileImage.layer.masksToBounds = YES;
Биджендра Сингх
источник
Блестящий взлом, особенно когда дело доходит до использования памяти - другие ответы потребуют вдвое больше памяти, чтобы мгновенно добавить эту границу. Совет от профессионала - если вы хотите просто добавить границу с одной стороны, вы также можете изменить границы. Отличный ответ!
judepereira
11

Если вы знаете размеры своего изображения, то добавление границы к слою UIImageView - лучшее решение AFAIK. На самом деле, вы можете просто установить для кадра imageView значения x, y, image.size.width, image.size.height.

Если у вас есть ImageView фиксированного размера с динамически загружаемыми изображениями, размер которых изменяется (или масштабируется до AspectFit), ваша цель - изменить размер изображения до нового изображения с измененным размером.

Самый короткий способ сделать это:

// containerView is my UIImageView
containerView.layer.borderWidth = 7;
containerView.layer.borderColor = [UIColor colorWithRed:0.22 green:0.22 blue:0.22 alpha:1.0].CGColor;

// this is the key command
[containerView setFrame:AVMakeRectWithAspectRatioInsideRect(image.size, containerView.frame)];

Но чтобы использовать AVMakeRectWithAspectRatioInsideRect, вам нужно добавить это

#import <AVFoundation/AVFoundation.h>

import в ваш файл, а также включите в свой проект фреймворк AVFoundation (поставляется в комплекте с SDK).

ScorpionKing2k5
источник
Спасибо @rafinskipg! Очень признателен.
ScorpionKing2k5
8

Вы не можете добавить границу, но это сработает для того же эффекта. Вы также можете превратить UIView с именем blackBG в этом примере в UIImageView с изображением границы и пустой серединой, и тогда у вас будет настраиваемая граница изображения вместо просто черной.

UIView *blackBG = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];

blackBG.backgroundColor = [UIColor blackColor];

UIImageView *myPicture = [[UIImageView alloc] initWithImage:
                          [UIImage imageNamed: @"myPicture.jpg"]];

int borderWidth = 10;

myPicture.frame = CGRectMake(borderWidth,
                             borderWidth,
                             blackBG.frame.size.width-borderWidth*2,
                             blackBG.frame.size.height-borderWidth*2)];

[blackBG addSubview: myPicture];
Эндрю Джонсон
источник
Вот что я в итоге сделал; Вложу мою UIImageViewв центр немного большего UIViewмоего цвета кадра.
Бен Кригер,
6

все эти ответы работают нормально, НО добавить прямоугольник к изображению. Предположим, у вас есть фигура (в моем случае бабочка), и вы хотите добавить границу (красную границу):

нам нужно два шага: 1) взять изображение, преобразовать его в CGImage, передать функции для рисования вне экрана в контексте с помощью CoreGraphics и вернуть новый CGImage

2) конвертируем обратно в uiimage и нарисуем:

// remember to release object!
+ (CGImageRef)createResizedCGImage:(CGImageRef)image toWidth:(int)width
andHeight:(int)height
{
// create context, keeping original image properties
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, width,
                                             height,
                                             8
                                             4 * width,
                                             colorspace,
                                             kCGImageAlphaPremultipliedFirst
                                             );

 CGColorSpaceRelease(colorspace);

if(context == NULL)
    return nil;

// draw image to context (resizing it)
CGContextSetInterpolationQuality(context, kCGInterpolationDefault);

CGSize offset = CGSizeMake(2,2);
CGFloat blur = 4;   
CGColorRef color = [UIColor redColor].CGColor;
CGContextSetShadowWithColor ( context, offset, blur, color);

CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
// extract resulting image from context
CGImageRef imgRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
return imgRef;

}

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

CGRect frame = CGRectMake(0,0,160, 122);
UIImage * img = [UIImage imageNamed:@"butterfly"]; // take low res OR high res, but frame should be the low-res one.
imgV = [[UIImageView alloc]initWithFrame:frame];
[imgV setImage: img];
imgV.center = self.view.center;
[self.view addSubview: imgV];

frame.size.width = frame.size.width * 1.3;
frame.size.height = frame.size.height* 1.3;
CGImageRef cgImage =[ViewController createResizedCGImage:[img CGImage] toWidth:frame.size.width andHeight: frame.size.height ];

imgV2 = [[UIImageView alloc]initWithFrame:frame];
[imgV2 setImage: [UIImage imageWithCGImage:cgImage] ];

// release:
if (cgImage) CGImageRelease(cgImage);

[self.view addSubview: imgV2];

}

Я добавил обычную бабочку и большую бабочку с красной каймой.

ingconti
источник
есть ли способ установить здесь ширину красной границы.
coder1010
5

Вы можете добавить границу к UIImageView, а затем изменить размер UIimageView в соответствии с размером изображения:

#import <QuartzCore/QuartzCore.h>


// adding border to the imageView
[imageView.layer setBorderColor: [[UIColor whiteColor] CGColor]];
[imageView.layer setBorderWidth: 2.0];

// resize the imageView to fit the image size
CGSize size = [image size];
float factor = size.width / self.frame.size.width;
if (factor < size.height / self.frame.size.height) {
    factor = size.height / self.frame.size.height;
}

CGRect rect = CGRectMake(0, 0, size.width/factor, size.height/factor);
imageView.frame = rect;

Убедитесь, что вы установили источник изображения в центре

põleb
источник
2

Вы можете манипулировать самим изображением, но гораздо лучше просто добавить UIView, содержащий UIImageView, и изменить фон на черный. Затем установите размер этого представления контейнера немного больше, чем размер UIImageView.

Кендалл Хельмштеттер Гельнер
источник
Будет ли он работать с изображениями другого размера, которые меняются на лету? UIImageView будет все время меняться, а UIView? ps Манипулировать самим изображением будет здорово.
Shay
Вам нужно будет настроить рамку содержащего представления вместе с изображением - вы можете сохранить свойства центра для обоих представлений, настроить размер изображения, настроить размер контейнера, а затем повторно установить свойства центра для обоих.
Кендалл Хелмштеттер Гельнер,
Я сделал это именно так, а не прокладывал путь с помощью компьютерной графики. просто казалось проще.
Кори Флойд,
2

Другой способ - сделать прямо у дизайнера.

Выберите свое изображение и перейдите в раздел «Показать инспектор идентичности».

Здесь вы можете вручную добавить « Пользовательские атрибуты времени выполнения» :

layer.borderColor
layer.borderWidth


введите описание изображения здесь

Лука Даванцо
источник
1
Это не сработает, так как вам нужен CGColor, а через XIB он предоставляет только UIColor
codenooker
Цвет не подойдет, но если вам просто нужен черный - это наиболее эффективный из «строк кода». Ответ = D
soprof
1

// вам нужно импортировать

QuartzCore/QuartzCore.h

а затем для ImageView в рамке

[imageView.layer setBorderColor: [[UIColor blackColor] CGColor]];

[imageView.layer setBorderWidth: 2.0];

[imageView.layer setCornerRadius: 5.0];
Panky
источник
1

Эта функция вернет вам изображение с черной рамкой, попробуйте это .. надеюсь, это поможет вам

- (UIImage *)addBorderToImage:(UIImage *)image frameImage:(UIImage *)blackBorderImage
{
    CGSize size = CGSizeMake(image.size.width,image.size.height);
    UIGraphicsBeginImageContext(size);

    CGPoint thumbPoint = CGPointMake(0,0);

    [image drawAtPoint:thumbPoint];


    UIGraphicsBeginImageContext(size);
    CGImageRef imgRef = blackBorderImage.CGImage;
    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, size.width,size.height), imgRef);
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CGPoint starredPoint = CGPointMake(0, 0);
    [imageCopy drawAtPoint:starredPoint];
    UIImage *imageC = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return imageC;
}
SachinVsSachin
источник
Если вы нашли какие-либо глиши, дайте мне знать ... я
улучшу
1

В Swift 3 вот как это делается с самим UIImage:

let size = CGSize(width: image.size.width, height: image.size.height)
UIGraphicsBeginImageContext(size)
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
image?.draw(in: rect, blendMode: .normal, alpha: 1.0)
let context = UIGraphicsGetCurrentContext()
context?.setStrokeColor(red: 0, green: 0, blue: 0, alpha: 1)
context?.stroke(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

self.imageView.image = newImage
CodyMace
источник
1

Для тех, кто ищет решение plug-and-play для UIImage, я написал ответ CodyMace в качестве расширения.

Использование: let outlined = UIImage(named: "something")?.outline()

extension UIImage {

    func outline() -> UIImage? {

        let size = CGSize(width: self.size.width, height: self.size.height)
        UIGraphicsBeginImageContext(size)
        let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        self.draw(in: rect, blendMode: .normal, alpha: 1.0)
        let context = UIGraphicsGetCurrentContext()
        context?.setStrokeColor(red: 0, green: 0, blue: 0, alpha: 1)
        context?.stroke(rect)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage

    }

}
Маврик Лааксо
источник
0

Я создал класс, который добавляет границу к imageView h. Используйте этот класс вместо UIImageView. Я дал отступ 4. Вы можете указать по своему желанию.

class UIBorderImageView: UIView {

private lazy var imageView: UIImageView = {
    let imageView = UIImageView()
    imageView.contentMode = .scaleAspectFit
    imageView.translatesAutoresizingMaskIntoConstraints = false
    return imageView
}()

override init(frame: CGRect) {
    super.init(frame: frame)
    self.backgroundColor = UIColor.White()
    self.layer.borderColor = UIColor.GreyMedium().cgColor
    self.layer.borderWidth = 1.0
    self.layer.cornerRadius = 4.0
    self.layer.masksToBounds = true
    self.setUpViews()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

private func setUpViews(){
    self.addSubview(imageView)
    self.addConstraintsWithFormat(format: "H:|-4-[v0]-4-|", views: imageView)
    self.addConstraintsWithFormat(format: "V:|-4-[v0]-4-|", views: imageView)
}

func configureImageViewWith(image:UIImage){
    self.imageview.image = image 
}}
Пранав Гупта
источник
-1

Я использую этот метод для добавления границы вне изображения . Вы можете установить boderWidthпостоянную ширину границы .

Swift 3

func addBorderToImage(image : UIImage) -> UIImage {
    let bgImage = image.cgImage
    let initialWidth = (bgImage?.width)!
    let initialHeight = (bgImage?.height)!
    let borderWidth = Int(Double(initialWidth) * 0.10);
    let width = initialWidth + borderWidth * 2
    let height = initialHeight + borderWidth * 2
    let data = malloc(width * height * 4)

    let context = CGContext(data: data,
                        width: width,
                        height: height,
                        bitsPerComponent: 8,
                        bytesPerRow: width * 4,
                        space: (bgImage?.colorSpace)!,
                        bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue);

    context?.draw(bgImage!, in: CGRect(x: CGFloat(borderWidth), y: CGFloat(borderWidth), width: CGFloat(initialWidth), height: CGFloat(initialHeight)))
    context?.setStrokeColor(UIColor.white.cgColor)
    context?.setLineWidth(CGFloat(borderWidth))
    context?.move(to: CGPoint(x: 0, y: 0))
    context?.addLine(to: CGPoint(x: 0, y: height))
    context?.addLine(to: CGPoint(x: width, y: height))
    context?.addLine(to: CGPoint(x: width, y: 0))
    context?.addLine(to: CGPoint(x: 0, y: 0))
    context?.strokePath()

    let cgImage = context?.makeImage()
    let uiImage = UIImage(cgImage: cgImage!)

    free(data)

    return uiImage;
}
Мигель Исла
источник