Wie kann ich ein UIImage nehmen und ihm einen schwarzen Rand geben?

126

Wie kann ich die Grenze von a setzen UIImage?

Shay
quelle
Wenn jemand (wie ich) zufällig von einer Google-Suche hört und nach einem Rahmen für UIImageView sucht, suchen Sie unten nach der Antwort von @mclin. Funktioniert super!
Mahendra Liya

Antworten:

241

Mit OS> 3.0 können Sie dies tun:

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

[imageView.layer setBorderColor: [[UIColor blackColor] CGColor]];
[imageView.layer setBorderWidth: 2.0];
mclin
quelle
1
Wenn ich die Bilder in der obigen Bildansicht anpasse, wird das Bild perfekt angezeigt, aber die Seiten des Bildes bleiben leer, und dasselbe passiert mit dem oberen und unteren Teil des Bildes, wenn das Bild im Querformat ist. Die Leerstelle sieht hässlich aus, wenn der Rand darauf gesetzt ist. Haben Sie sich diesem Problem gestellt? Wenn ja, schlagen Sie bitte eine Methode vor, um dieses
Problem
@ Hamutsi imageView.image = myImage;
Kyle Clegg
6
Ja, du kannst. Instanzen von UIImagekönnen mit CoreGraphics in einen Grafikkontext gezogen werden.
Mark Adams
Wie @rockstar hervorhebt, müssen Sie möglicherweise imageView.layer.masksToBounds = YES hinzufügen.
Björn Roche
Dieser Link war die Lösung, nach der ich gesucht habe.
GrandSteph
67

Sie können dies tun, indem Sie ein neues Bild erstellen (auch in Ihrem anderen Beitrag zu dieser Frage beantwortet):

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

Dieser Code erzeugt einen rosa Rand um das Bild. Wenn Sie jedoch nur den Rand anzeigen möchten, verwenden Sie die Ebene von UIImageViewund legen Sie den Rand fest.

Marcus S. Zarra
quelle
Wie legen Sie die Breite des gewünschten Rahmens fest?
Patrick
16
CGContextSetLineWidth
Marcus S. Zarra
@ MarcusS.Zarra Mir ist klar, dass sie nicht existierten, als diese Frage beantwortet wurde, aber diese Lösung berücksichtigt nicht das Retina-Display. Wenn Sie es überarbeiten könnten, wäre ich wirklich dankbar :)
Luke
@lukech Das Beispiel muss nicht überarbeitet werden. Erhöhen Sie einfach die Linienbreite, wenn Sie sich auf einem Netzhautgerät befinden.
Marcus S. Zarra
2
Das sizeist 320x480, unabhängig davon, ob Sie sich auf einem Retina-Gerät befinden oder nicht. Wenn Sie das Bild speichern, wird es mit dieser Auflösung von 320x480px und nicht mit 640x960 gespeichert.
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;    

Dieser Code kann zum Hinzufügen eines UIImageViewAnsichtsrahmens verwendet werden.

Faizan Refai
quelle
perfekt! Sie müssen sich nicht um CGImage kümmern. (Ich musste das Bild nicht mit dem Rand speichern). Vielen Dank!
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
quelle
Genialer Hack, besonders wenn es um die Speichernutzung geht - die anderen Antworten benötigen 2x Speicher, um diesen Rand vorübergehend hinzuzufügen. Profi-Tipp - Wenn Sie nur einen Rand auf einer Seite hinzufügen möchten, können Sie auch die Grenzen ändern. Gute Antwort!
Judepereira
11

Wenn Sie die Abmessungen Ihres Bildes kennen, ist das Hinzufügen eines Rahmens zur Ebene von UIImageView die beste Lösung für AFAIK. Tatsächlich können Sie Ihre Bildansicht einfach auf x, y, image.size.width, image.size.height setzen

Wenn Sie eine Bildansicht mit fester Größe und dynamisch geladenen Bildern haben, deren Größe geändert (oder auf AspectFit skaliert) wird, besteht Ihr Ziel darin, die Bildansicht auf das neue Bild mit geänderter Größe zu ändern.

Der kürzeste Weg dazu:

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

Um AVMakeRectWithAspectRatioInsideRect zu verwenden, müssen Sie dies hinzufügen

#import <AVFoundation/AVFoundation.h>

Importieren Sie die Anweisung in Ihre Datei und fügen Sie auch das AVFoundation-Framework in Ihr Projekt ein (im Lieferumfang des SDK enthalten).

ScorpionKing2k5
quelle
Danke @rafinskipg! Sehr geschätzt.
ScorpionKing2k5
8

Sie können keinen Rahmen hinzufügen, dies würde jedoch für denselben Effekt funktionieren. Sie können die UIView mit dem Namen blackBG in diesem Beispiel auch in eine UIImageView mit einem Rahmenbild und einer leeren Mitte verwandeln. Dann hätten Sie einen benutzerdefinierten Bildrahmen anstelle von nur Schwarz.

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
quelle
Das habe ich letztendlich getan; Nesting meine UIImageViewin der Mitte einer etwas größeren UIViewmeiner Rahmenfarbe.
Ben Kreeger
6

Alle diese Antworten funktionieren gut, ABER fügen Sie einem Bild ein Rechteck hinzu. Angenommen, Sie haben eine Form (in meinem Fall einen Schmetterling) und möchten einen Rand (einen roten Rand) hinzufügen:

Wir brauchen zwei Schritte: 1) Nehmen Sie das Bild, konvertieren Sie es in CGImage, übergeben Sie es an eine Funktion, um mit CoreGraphics außerhalb des Bildschirms in einem Kontext zu zeichnen, und geben Sie ein neues CGImage zurück

2) konvertiere zu uiimage zurück und zeichne:

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

}}

Ich fügte einen normalen Schmetterling und einen rot umrandeten größeren Schmetterling hinzu.

ingconti
quelle
Gibt es eine Möglichkeit, die Breite des roten Randes hier einzustellen?
coder1010
5

Sie können der UIImageView einen Rahmen hinzufügen und dann die Größe der UIimageView entsprechend der Bildgröße ändern:

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

Stellen Sie sicher, dass Sie den Ursprung der Bildansicht auf die Mitte setzen

polB
quelle
2

Sie können das Bild selbst bearbeiten. Eine viel bessere Möglichkeit besteht darin, einfach eine UIView hinzuzufügen, die die UIImageView enthält, und den Hintergrund in Schwarz zu ändern. Stellen Sie dann die Größe dieser Containeransicht etwas größer als die UIImageView ein.

Kendall Helmstetter Gelner
quelle
Funktioniert es mit einer anderen Größe von Bildern, die sich im laufenden Betrieb ändern? Das UIImageView ändert sich ständig, und das UIView? ps Das Bild selbst zu manipulieren ist großartig.
Shay
Sie müssten den Rahmen der enthaltenen Ansicht zusammen mit dem Bild anpassen. Sie könnten die Center-Eigenschaften für beide Ansichten speichern, die Bildgröße anpassen, die Containergröße anpassen und dann die Center-Eigenschaften für beide Ansichten zurücksetzen.
Kendall Helmstetter Gelner
Dies ist genau die Art und Weise, wie ich es getan habe, anstatt den Weg mit CG zu streicheln. schien einfach einfacher.
Corey Floyd
2

Eine andere Möglichkeit ist, direkt vom Designer zu tun.

Wählen Sie Ihr Bild aus und gehen Sie unter "Identitätsinspektor anzeigen".

Hier können Sie manuell " Benutzerdefinierte Laufzeitattribute" hinzufügen :

layer.borderColor
layer.borderWidth


Geben Sie hier die Bildbeschreibung ein

Luca Davanzo
quelle
1
Dies wird nicht funktionieren, da Sie CGColor benötigen und über XIB nur UIColor
Codesnooker
Farbe wird nicht funktionieren, aber wenn Sie nur eine schwarze brauchen - dies ist die effizienteste Antwort "Codezeilen" = D
soprof
1

// Sie müssen importieren

QuartzCore/QuartzCore.h

& dann für ImageView im Rahmen

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

[imageView.layer setBorderWidth: 2.0];

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

Diese Funktion gibt Ihnen ein Bild mit schwarzem Rand zurück. Versuchen Sie dies. Ich hoffe, dies wird Ihnen helfen

- (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
quelle
Wenn Sie irgendwelche Klischees gefunden haben, lassen Sie es mich bitte wissen ... ich werde es verbessern
SachinVsSachin
1

In Swift 3 machen Sie Folgendes mit dem UIImage selbst:

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

Für diejenigen, die nach einer Plug-and-Play-Lösung für UIImage suchen, habe ich die Antwort von CodyMace als Erweiterung geschrieben.

Verwendung: 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
quelle
0

Ich habe eine Klasse erstellt, die imageView h einen Rahmen hinzufügt. Verwenden Sie diese Klasse anstelle von UIImageView. Ich habe eine Auffüllung von 4 angegeben. Sie können nach Ihren Wünschen angeben.

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

Ich benutze diese Methode, um einen Rand außerhalb des Bildes hinzuzufügen . Sie können die Rahmenbreite boderWidthkonstant anpassen .

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
quelle