Bagaimana saya bisa mengambil UIImage dan memberinya perbatasan hitam?

126

Bagaimana cara mengatur batas a UIImage?

Shay
sumber
Secara kebetulan jika ada yang mendengar dengan pencarian google (seperti yang saya lakukan) dan mencari untuk menambahkan perbatasan ke UIImageView, cari jawabannya oleh @ Mclin di bagian bawah. Bagus sekali!
Mahendra Liya

Jawaban:

241

Dengan OS> 3.0 Anda dapat melakukan ini:

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

[imageView.layer setBorderColor: [[UIColor blackColor] CGColor]];
[imageView.layer setBorderWidth: 2.0];
mclin
sumber
1
Ketika saya aspekFit gambar dalam gambar di atas, gambar dilihat dengan sempurna tetapi sisi gambar dibiarkan kosong, dan hal yang sama terjadi pada bagian atas dan bawah gambar ketika gambar lanskap. Ruang kosong terlihat jelek dengan batas diatur ke sana .. Apakah Anda menghadapi masalah ini? Jika ya, harap sarankan metode untuk menyelesaikan ini
Temui
@Hamutsi imageView.image = myImage;
Kyle Clegg
6
Ya kamu bisa. Contoh dari UIImagedapat ditarik ke dalam konteks grafik dengan CoreGraphics.
Mark Adams
Seperti yang ditunjukkan @rockstar, Anda mungkin perlu menambahkan imageView.layer.masksToBounds = YA;
Bjorn Roche
Tautan ini adalah solusi yang saya cari.
GrandSteph
67

Anda dapat melakukan ini dengan membuat gambar baru (juga dijawab dalam posting Anda yang lain dari pertanyaan ini):

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

Kode ini akan menghasilkan batas berwarna merah muda di sekitar gambar. Namun jika Anda hanya akan menampilkan perbatasan maka gunakan layer UIImageViewdan atur perbatasannya.

Marcus S. Zarra
sumber
Bagaimana Anda menentukan lebar perbatasan yang Anda inginkan?
Patrick
16
CGContextSetLineWidth
Marcus S. Zarra
@ MarcusS.Zarra Saya menyadari bahwa mereka tidak ada ketika pertanyaan ini dijawab, tetapi solusi ini tidak mempertimbangkan tampilan Retina. Jika Anda dapat merevisinya, saya akan sangat berterima kasih :)
Luke
@ lukech Sampel tidak perlu direvisi. Cukup tambahkan lebar garis jika Anda menggunakan perangkat retina.
Marcus S. Zarra
2
Ini sizeadalah 320x480 terlepas dari apakah Anda menggunakan perangkat Retina atau tidak, jadi ketika Anda menyimpan gambar, ia menyimpan resolusi 320x480px itu, bukan 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;    

Kode ini dapat digunakan untuk menambahkan UIImageViewbatas tampilan.

Refai Faizan
sumber
sempurna! Tidak perlu melalui kerumitan CGImage. (Saya tidak perlu menyimpan gambar dengan perbatasan). Terima kasih banyak!
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
sumber
Retas yang brilian, terutama dalam hal penggunaan memori - jawaban yang lain akan membutuhkan 2x memori hanya untuk menambahkan batas itu sejenak. Kiat pro - Jika Anda ingin menambahkan batas di satu sisi, maka Anda juga dapat mengubah batas. Jawaban bagus!
judepereira
11

Jika Anda mengetahui dimensi gambar Anda, maka menambahkan perbatasan ke lapisan UIImageView adalah solusi terbaik AFAIK. Infact, Anda dapat mengaturFrame imageView Anda ke x, y, image.size.width, image.size.height

Jika Anda memiliki ImageView ukuran tetap dengan gambar yang dimuat secara dinamis yang diubah ukurannya (atau diskalakan ke AspectFit), maka tujuan Anda adalah mengubah ukuran tampilan gambar ke gambar yang baru diubah ukurannya.

Cara terpendek untuk melakukan ini:

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

Tetapi untuk menggunakan AVMakeRectWithAspectRatioInsideRect, Anda perlu menambahkan ini

#import <AVFoundation/AVFoundation.h>

impor pernyataan ke file Anda dan sertakan juga kerangka kerja AVFoundation dalam proyek Anda (dibundel dengan SDK).

ScorpionKing2k5
sumber
Terima kasih @rafinskipg! Sangat dihargai.
ScorpionKing2k5
8

Anda tidak dapat menambahkan perbatasan, tetapi ini akan bekerja untuk efek yang sama. Anda juga bisa membuat UIView yang disebut blackBG dalam contoh ini menjadi UIImageView dengan gambar tepi dan tengah kosong, dan kemudian Anda akan memiliki batas gambar khusus bukan hanya hitam.

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
sumber
Inilah yang akhirnya saya lakukan; bersarang saya UIImageViewdi tengah sedikit lebih besar UIViewdari warna bingkai saya.
Ben Kreeger
6

semua jawaban ini berfungsi dengan baik TETAPI menambahkan sebuah persegi ke gambar. Misalkan Anda memiliki bentuk (dalam kasus saya kupu-kupu) dan Anda ingin menambahkan perbatasan (perbatasan merah):

kita perlu dua langkah: 1) mengambil gambar, mengonversi ke CGImage, beralih ke fungsi untuk menggambar di luar layar dalam konteks menggunakan CoreGraphics, dan memberikan kembali CGImage baru

2) konversi ke uiimage kembali dan menggambar:

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

}

Saya menambahkan kupu-kupu normal dan kupu-kupu besar berbatasan-merah.

ingconti
sumber
apakah ada cara untuk mengatur lebar perbatasan merah di sini.
coder1010
5

Anda dapat menambahkan perbatasan ke UIImageView, dan kemudian mengubah ukuran UIimageView sesuai dengan ukuran gambar:

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

Pastikan Anda mengatur asal imageView ke tengah

poleB
sumber
2

Anda dapat memanipulasi gambar itu sendiri, tetapi cara yang jauh lebih baik adalah dengan hanya menambahkan UIView yang berisi UIImageView, dan mengubah latar belakang menjadi hitam. Kemudian atur ukuran tampilan kontainer menjadi sedikit lebih besar dari UIImageView.

Kendall Helmstetter Gelner
sumber
Apakah akan bekerja dengan ukuran gambar berbeda yang berubah dengan cepat? UIImageView akan berubah setiap saat, dan UIView? ps Memanipulasi gambar itu sendiri akan menjadi hebat.
Shay
Anda harus menyesuaikan bingkai tampilan yang berisi gambar - Anda bisa menghemat properti pusat untuk kedua tampilan, menyesuaikan ukuran gambar, menyesuaikan ukuran wadah, dan kemudian mengatur ulang properti pusat untuk keduanya.
Kendall Helmstetter Gelner
Ini persis seperti yang saya lakukan sebagai lawan membelai jalan dengan CG. sepertinya lebih mudah.
Corey Floyd
2

Cara lain adalah dengan melakukan langsung dari desainer.

Pilih gambar Anda dan pilih "Tampilkan inspektur Identitas".

Di sini Anda dapat secara manual menambahkan " Atribut Runtime yang Ditentukan Pengguna" :

layer.borderColor
layer.borderWidth


masukkan deskripsi gambar di sini

Luca Davanzo
sumber
1
Ini tidak akan berfungsi karena Anda membutuhkan CGColor dan melalui XIB hanya menyediakan UIColor
codesnooker
Warna tidak akan berfungsi, tetapi jika Anda hanya membutuhkan yang hitam - ini adalah jawaban paling efisien "baris kode" = D
soprof
1

// Anda perlu mengimpor

QuartzCore/QuartzCore.h

& lalu untuk ImageView di perbatasan

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

[imageView.layer setBorderWidth: 2.0];

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

Fungsi ini akan mengembalikan gambar Anda dengan batas hitam coba ini .. harap ini akan membantu Anda

- (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
sumber
Jika Anda menemukan gliches, tolong beri tahu saya ... saya akan memperbaikinya
SachinVsSachin
1

Di Swift 3 inilah cara Anda melakukannya ke UIImage itu sendiri:

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

Bagi mereka yang mencari solusi plug-and-play di UIImage, saya menulis jawaban CodyMace sebagai ekstensi.

Pemakaian: 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
sumber
0

Saya telah membuat kelas yang menambahkan perbatasan ke imageView h. Gunakan kelas ini sebagai ganti UIImageView. Saya telah memberikan padding 4. Anda dapat memberikan sesuai keinginan Anda.

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

Saya menggunakan metode ini untuk menambahkan perbatasan di luar gambar . Anda dapat menyesuaikan lebar perbatasan dalamboderWidth konstan.

Cepat 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
sumber