Comment puis-je prendre une UIImage et lui donner une bordure noire?

126

Comment puis-je définir la bordure d'un UIImage?

Shay
la source
Par chance, si quelqu'un atterrit lors d'une recherche Google (comme je l'ai fait) et cherche à ajouter une bordure à UIImageView, recherchez la réponse par @mclin en bas. Fonctionne très bien!
Mahendra Liya

Réponses:

241

Avec OS> 3.0, vous pouvez faire ceci:

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

[imageView.layer setBorderColor: [[UIColor blackColor] CGColor]];
[imageView.layer setBorderWidth: 2.0];
mclin
la source
1
Lorsque i aspectFit les images dans l'image ci-dessus, l'image est parfaitement visualisée mais les côtés de l'image sont laissés vierges, et il en va de même pour la partie supérieure et inférieure de l'image lorsque l'image est en mode paysage. L'espace vide semble moche avec une bordure définie. Avez-vous rencontré ce problème? Si oui, s'il vous plaît suggérer une méthode pour résoudre ce
Rencontre
@Hamutsi imageView.image = monImage;
Kyle Clegg
6
Oui, vous pouvez. Les instances de UIImagepeuvent être dessinées dans un contexte graphique avec CoreGraphics.
Mark Adams
Comme le souligne @rockstar, vous devrez peut-être ajouter imageView.layer.masksToBounds = YES;
Bjorn Roche
Ce lien était la solution que je recherchais.
GrandSteph
67

Vous pouvez le faire en créant une nouvelle image (également répondu dans votre autre publication de cette question):

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

Ce code produira une bordure rose autour de l'image. Cependant, si vous souhaitez simplement afficher la bordure, utilisez le calque du UIImageViewet définissez sa bordure.

Marcus S. Zarra
la source
Comment spécifiez-vous la largeur de la bordure souhaitée?
Patrick
16
CGContextSetLineWidth
Marcus S.Zarra
@ MarcusS.Zarra Je me rends compte qu'ils n'existaient pas lorsque cette question a été répondue, mais cette solution ne prend pas en compte l'écran Retina. Si vous pouviez le réviser, je vous serais vraiment reconnaissant :)
Luc
@lukech L'échantillon n'a pas besoin d'être révisé. Augmentez simplement la largeur de la ligne si vous utilisez un appareil Retina.
Marcus S.Zarra
2
Le sizeformat est de 320x480, que vous soyez ou non sur un appareil Retina, donc lorsque vous enregistrez l'image, il enregistre à cette résolution de 320x480px, pas 640x960.
Luke
38
#import <QuartzCore/CALayer.h>


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

Ce code peut être utilisé pour ajouter une UIImageViewbordure de vue.

Faizan Refai
la source
parfait! Pas besoin de passer par les tracas de CGImage. (Je n'ai pas eu besoin de sauvegarder l'image avec la bordure). Merci beaucoup!
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
la source
Astuce géniale, surtout en ce qui concerne l'utilisation de la mémoire - les autres réponses prendront 2x de mémoire juste pour ajouter momentanément cette frontière. Conseil de pro - Si vous souhaitez simplement ajouter une bordure sur un côté, vous pouvez également modifier les limites. Très bonne réponse!
judepereira
11

Si vous connaissez les dimensions de votre image, alors l'ajout d'une bordure au calque d'UIImageView est la meilleure solution AFAIK. En fait, vous pouvez simplement définirFrame votre imageView sur x, y, image.size.width, image.size.height

Dans le cas où vous avez un ImageView d'une taille fixe avec des images chargées dynamiquement qui sont redimensionnées (ou mises à l'échelle à AspectFit), votre objectif est de redimensionner l'imageview à la nouvelle image redimensionnée.

Le moyen le plus court de le faire:

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

Mais pour utiliser AVMakeRectWithAspectRatioInsideRect, vous devez ajouter ceci

#import <AVFoundation/AVFoundation.h>

importation dans votre fichier et incluez également le framework AVFoundation dans votre projet (livré avec le SDK).

ScorpionKing2k5
la source
Merci @rafinskipg! Très appréciée.
ScorpionKing2k5
8

Vous ne pouvez pas ajouter de bordure, mais cela fonctionnerait pour le même effet. Vous pouvez également transformer l'UIView appelé blackBG dans cet exemple en une UIImageView avec une image de bordure et un milieu vide, puis vous auriez une bordure d'image personnalisée au lieu de simplement noire.

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
la source
C'est ce que j'ai fini par faire; nichant mon UIImageViewau centre d'une UIViewcouleur légèrement plus grande de mon cadre.
Ben Kreeger
6

toutes ces réponses fonctionnent bien MAIS ajouter un rect à une image. Supposons que vous ayez une forme (dans mon cas un papillon) et que vous vouliez ajouter une bordure (une bordure rouge):

nous avons besoin de deux étapes: 1) prendre l'image, convertir en CGImage, passer à une fonction pour dessiner hors écran dans un contexte utilisant CoreGraphics, et rendre une nouvelle CGImage

2) convertir en uiimage et dessiner:

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

}

J'ai ajouté un papillon normal et un papillon plus gros bordé de rouge.

ingconti
la source
y a-t-il un moyen de définir la largeur de la bordure rouge ici.
coder1010
5

Vous pouvez ajouter une bordure à UIImageView, puis modifier la taille de UIimageView en fonction de la taille de l'image:

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

Assurez-vous de définir l'origine de l'imageView au centre

pôleB
la source
2

Vous pouvez manipuler l'image elle-même, mais une bien meilleure façon consiste simplement à ajouter un UIView qui contient l'UIImageView et à changer l'arrière-plan en noir. Ensuite, définissez la taille de cette vue de conteneur sur un peu plus grande que UIImageView.

Kendall Helmstetter Gelner
la source
Va-t-il fonctionner avec une taille d'images différente qui change à la volée? Le UIImageView changera tout le temps, et le UIView? ps Manipuler l'image elle-même sera génial.
Shay
Vous devrez ajuster le cadre de la vue contenant avec l'image - vous pouvez enregistrer les propriétés du centre pour les deux vues, ajuster la taille de l'image, ajuster la taille du conteneur, puis redéfinir les propriétés du centre pour les deux.
Kendall Helmstetter Gelner
C'est exactement comme ça que je l'ai fait plutôt que de caresser le chemin avec CG. semblait juste plus facile.
Corey Floyd
2

Une autre façon est de faire directement à partir du concepteur.

Sélectionnez votre image et allez sous "Afficher l'inspecteur d'identité".

Ici, vous pouvez ajouter manuellement des " Attributs d'exécution définis par l'utilisateur" :

layer.borderColor
layer.borderWidth


entrez la description de l'image ici

Luca Davanzo
la source
1
Cela ne fonctionnera pas car vous avez besoin de CGColor et via XIB, il ne fournit que UIColor
codesnooker
La couleur ne fonctionnera pas, mais si vous avez juste besoin d'un noir - c'est la réponse la plus efficace pour les "lignes de code" = D
soprof
1

// vous devez importer

QuartzCore/QuartzCore.h

& puis pour ImageView en bordure

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

[imageView.layer setBorderWidth: 2.0];

[imageView.layer setCornerRadius: 5.0];
Panky
la source
1

Cette fonction vous renverra une image avec une bordure noire essayez ceci.

- (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
la source
Si vous avez trouvé des problèmes, faites-le moi savoir ... je vais l'améliorer
SachinVsSachin
1

Dans Swift 3, voici comment procéder pour l'interface utilisateur elle-même:

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
la source
1

Pour ceux qui recherchent une solution plug-and-play sur UIImage, j'ai écrit la réponse de CodyMace en tant qu'extension.

Usage: 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
la source
0

J'ai créé une classe qui ajoute une bordure à imageView h. Utilisez cette classe au lieu de UIImageView. J'ai donné un remplissage de 4. Vous pouvez donner selon votre souhait.

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
la source
-1

J'utilise cette méthode pour ajouter une bordure à l'extérieur de l'image . Vous pouvez personnaliser la largeur de la bordure 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
la source