¿Cómo puedo tomar un UIImage y darle un borde negro?

126

¿Cómo puedo establecer el borde de a UIImage?

Shay
fuente
Por casualidad, si alguien llega a escuchar por una búsqueda en Google (como lo hice yo) y está buscando agregar un borde a UIImageView, busque la respuesta por @mclin en la parte inferior. ¡Funciona genial!
Mahendra Liya

Respuestas:

241

Con OS> 3.0 puedes hacer esto:

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

[imageView.layer setBorderColor: [[UIColor blackColor] CGColor]];
[imageView.layer setBorderWidth: 2.0];
Mclin
fuente
1
Cuando aspecto las imágenes en la vista de imagen anterior, la imagen se ve perfectamente pero los lados de la imagen se dejan en blanco, y lo mismo ocurre con la parte superior e inferior de la imagen cuando la imagen es horizontal. El espacio en blanco se ve feo con el borde establecido. ¿Te enfrentaste a este problema? En caso afirmativo, sugiera un método para resolver esto
conozca el
@Hamutsi imageView.image = myImage;
Kyle Clegg
66
Sí tu puedes. Las instancias de UIImagese pueden dibujar en un contexto gráfico con CoreGraphics.
Mark Adams
Como señala @rockstar, es posible que deba agregar imageView.layer.masksToBounds = YES;
Bjorn Roche
Este enlace fue la solución que estaba buscando.
GrandSteph
67

Puede hacer esto creando una nueva imagen (también respondida en su otra publicación de esta pregunta):

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

Este código producirá un borde rosado alrededor de la imagen. Sin embargo, si solo va a mostrar el borde, use la capa UIImageViewy establezca su borde.

Marcus S. Zarra
fuente
¿Cómo se especifica el ancho del borde que desea?
Patrick
16
CGContextSetLineWidth
Marcus S. Zarra
@ MarcusS.Zarra Me doy cuenta de que no existían cuando se respondió esta pregunta, pero esta solución no tiene en cuenta la pantalla Retina. Si pudieras revisarlo, estaría muy agradecido :)
Luke
@lukech La muestra no necesita ser revisada. Simplemente aumente el ancho de línea si está en un dispositivo de retina.
Marcus S. Zarra
2
El sizees 320x480 independientemente de si está o no en un dispositivo Retina, por lo que cuando guarda la imagen, se guarda con esa resolución de 320x480px, no 640x960.
Lucas
38
#import <QuartzCore/CALayer.h>


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

Este código se puede usar para agregar un UIImageViewborde de vista.

Faizan Refai
fuente
¡Perfecto! No es necesario pasar por la molestia de CGImage. (No necesitaba guardar la imagen con el borde). ¡Gracias un montón!
Septronic
13
imageView_ProfileImage.layer.cornerRadius =10.0f;
imageView_ProfileImage.layer.borderColor = [[UIColor blackColor] CGColor];
imageView_ProfileImage.layer.borderWidth =.4f;
imageView_ProfileImage.layer.masksToBounds = YES;
Bijendra Singh
fuente
Hack brillante, especialmente cuando se trata del uso de memoria: las otras respuestas tomarán 2 veces más memoria solo para agregar ese borde momentáneamente. Consejo profesional: si solo desea agregar un borde en un lado, también puede cambiar los límites. ¡Gran respuesta!
judepereira
11

Si conoce las dimensiones de su imagen, entonces agregar un borde a la capa de UIImageView es la mejor solución AFAIK. De hecho, simplemente puede configurar enmarcar su imageView a x, y, image.size.width, image.size.height

En caso de que tenga un ImageView de un tamaño fijo con imágenes cargadas dinámicamente que se están redimensionando (o escalando a AspectFit), entonces su objetivo es cambiar el tamaño de la vista de imagen a la nueva imagen redimensionada.

La forma más corta de hacer esto:

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

Pero para usar AVMakeRectWithAspectRatioInsideRect, debe agregar esto

#import <AVFoundation/AVFoundation.h>

importe la declaración a su archivo y también incluya el marco AVFoundation en su proyecto (viene incluido con el SDK).

ScorpionKing2k5
fuente
Gracias @rafinskipg! Muy apreciado.
ScorpionKing2k5
8

No puede agregar un borde, pero esto funcionaría para el mismo efecto. También podría convertir el UIView llamado blackBG en este ejemplo en un UIImageView con una imagen de borde y un centro en blanco, y luego tendría un borde de imagen personalizado en lugar de solo negro.

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];
Andrew Johnson
fuente
Esto es lo que terminé haciendo; anidando mi UIImageViewen el centro de un UIViewcolor un poco más grande de mi marco.
Ben Kreeger el
6

todas estas respuestas funcionan bien PERO agregan un rect a una imagen. Supongamos que tiene una forma (en mi caso, una mariposa) y desea agregar un borde (un borde rojo):

necesitamos dos pasos: 1) tomar la imagen, convertirla a CGImage, pasar a una función para dibujar fuera de la pantalla en un contexto usando CoreGraphics y devolver una nueva CGImage

2) convertir a uiimage de nuevo y dibujar:

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

}

Agregué una mariposa normal y una mariposa más grande con borde rojo.

ingconti
fuente
¿Hay alguna manera de establecer el ancho del borde rojo aquí?
coder1010
5

Puede agregar borde al UIImageView y luego cambiar el tamaño del UIimageView de acuerdo con el tamaño de la imagen:

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

Asegúrese de establecer el origen de imageView en el centro

poloB
fuente
2

Puede manipular la imagen en sí, pero una forma mucho mejor es simplemente agregar una vista UIView que contenga el UIImageView y cambiar el fondo a negro. Luego configure el tamaño de esa vista de contenedor a un poco más grande que UIImageView.

Kendall Helmstetter Gelner
fuente
¿Funcionará con un tamaño diferente de imágenes que cambian sobre la marcha? ¿El UIImageView cambiará todo el tiempo y el UIView? ps Manipular la imagen en sí será genial.
Shay
Tendría que ajustar el marco de la vista que lo contiene junto con la imagen; podría guardar las propiedades del centro para ambas vistas, ajustar el tamaño de la imagen, ajustar el tamaño del contenedor y luego restablecer las propiedades del centro para ambas.
Kendall Helmstetter Gelner
Esta es exactamente la forma en que lo hice en lugar de trazar el camino con CG. Simplemente parecía más fácil.
Corey Floyd el
2

Otra forma es hacerlo directamente desde el diseñador.

Seleccione su imagen y vaya a "Mostrar el inspector de identidad".

Aquí puede agregar manualmente " Atributos de tiempo de ejecución definidos por el usuario" :

layer.borderColor
layer.borderWidth


ingrese la descripción de la imagen aquí

Luca Davanzo
fuente
1
Esto no va a funcionar ya que necesita CGColor y a través de XIB solo proporciona UIColor
codenooker
El color no funcionará, pero si solo necesita uno negro, esta es la respuesta eficiente más "líneas de código" = D
soprof
1

// necesitas importar

QuartzCore/QuartzCore.h

y luego para ImageView en el borde

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

[imageView.layer setBorderWidth: 2.0];

[imageView.layer setCornerRadius: 5.0];
Panky
fuente
1

Esta función te devolverá la imagen con borde negro. Prueba esto. Espero que esto te ayude.

- (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
fuente
Si encontraste algún gliches, por favor avísame ... lo
mejoraré
1

En Swift 3, así es como lo haces al UIImage en sí:

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
fuente
1

Para aquellos que buscan una solución plug-and-play en UIImage, escribí la respuesta de CodyMace como una extensión.

Uso: 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

    }

}
Mavrick Laakso
fuente
0

He creado una clase que agrega un borde a imageView h. Utilice esta clase en lugar de UIImageView. Le he dado un relleno de 4. Puede dar según su deseo.

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 
}}
Pranav Gupta
fuente
-1

Yo uso este método para agregar un borde fuera de la imagen . Puede personalizar el ancho del borde en boderWidthconstante.

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;
}
Miguel Isla
fuente