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


Ответы:


241

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

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

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

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).


Спасибо @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];

}

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


есть ли способ установить здесь ширину красной границы.
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;

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


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

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

Если вы нашли какие-либо глиши, дайте мне знать ... я
улучшу

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

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;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.