2015-03-14 14 views
24

Bir çember içine UIImage kesmek istiyorum, böylece bir ek açıklama olarak kullanabilirsiniz. Bulduğum bu sitedeki her yanıt bir UIImageView oluşturmayı, ardından bunu değiştirip görüntülemeyi anlatıyor, ancak bir ek açıklama görüntüsünü UIImageView, yalnızca UIImage olarak ayarlayamazsınız. Bunun için nasıl gitmeliyim?Bir daire içine UIImage kesiyor

cevap

28

Gerekirse QuarzCore aldığınızdan emin olun.

func maskRoundedImage(image: UIImage, radius: CGFloat) -> UIImage { 
     let imageView: UIImageView = UIImageView(image: image) 
     let layer = imageView.layer 
     layer.masksToBounds = true 
     layer.cornerRadius = radius 
     UIGraphicsBeginImageContext(imageView.bounds.size) 
     layer.render(in: UIGraphicsGetCurrentContext()!) 
     let roundedImage = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 
     return roundedImage! 
    } 
+0

Bu ayrıca çalışır, teşekkürler dostum! – Learnin

+0

İyi düşünmüştüm, kontrol ettim ve QuartzCore'u ve herşeyi ithal ettim. İşe yarayıp yaramadığını kontrol edebilir misin? – Learnin

+0

Evet, bir oyun alanında kontrol ettim. –

1

Ben BezierPath bir kullanımını bularak kendi soruya cevap başardı!

if let xyz = UIImage(contentsOfFile: readPath) { 
    var Rect: CGRect = CGRectMake(0, 0, xyz.size.width, xyz.size.height) 
    var x = UIBezierPath(roundedRect: Rect, cornerRadius: 200).addClip() 

    UIGraphicsBeginImageContextWithOptions(xyz.size, false, xyz.scale) 
    xyz.drawInRect(Rect) 
    var ImageNew = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
    annotation.image = ImageNew 
} 
63

Xcode 8.2 • Swift 3.0.2

extension UIImage { 
    var isPortrait: Bool { return size.height > size.width } 
    var isLandscape: Bool { return size.width > size.height } 
    var breadth:  CGFloat { return min(size.width, size.height) } 
    var breadthSize: CGSize { return CGSize(width: breadth, height: breadth) } 
    var breadthRect: CGRect { return CGRect(origin: .zero, size: breadthSize) } 
    var circleMasked: UIImage? { 
     UIGraphicsBeginImageContextWithOptions(breadthSize, false, scale) 
     defer { UIGraphicsEndImageContext() } 
     guard let cgImage = cgImage?.cropping(to: CGRect(origin: CGPoint(x: isLandscape ? floor((size.width - size.height)/2) : 0, y: isPortrait ? floor((size.height - size.width)/2) : 0), size: breadthSize)) else { return nil } 
     UIBezierPath(ovalIn: breadthRect).addClip() 
     UIImage(cgImage: cgImage, scale: 1, orientation: imageOrientation).draw(in: breadthRect) 
     return UIGraphicsGetImageFromCurrentImageContext() 
    } 
} 

Bahçesi Testi

let profilePicture = UIImage(data: try! Data(contentsOf: URL(string:"http://i.stack.imgur.com/Xs4RX.jpg")!))! 
profilePicture.circleMasked 

+1

Mükemmel. Teşekkürler. – Vakas

+0

Harika! Teşekkürler. Ancak, oldukça pikselli bir kenarlık eklerseniz. Bu nasıl düzeltilebilir? – jonas

+1

Parlak! Bir süredir bu konuya takıldım, teşekkürler! –

6

UIImage uzantısı:

extension UIImage { 

    func circularImage(size size: CGSize?) -> UIImage { 
     let newSize = size ?? self.size 

     let minEdge = min(newSize.height, newSize.width) 
     let size = CGSize(width: minEdge, height: minEdge) 

     UIGraphicsBeginImageContextWithOptions(size, false, 0.0) 
     let context = UIGraphicsGetCurrentContext() 

     self.drawInRect(CGRect(origin: CGPoint.zero, size: size), blendMode: .Copy, alpha: 1.0) 

     CGContextSetBlendMode(context, .Copy) 
     CGContextSetFillColorWithColor(context, UIColor.clearColor().CGColor) 

     let rectPath = UIBezierPath(rect: CGRect(origin: CGPoint.zero, size: size)) 
     let circlePath = UIBezierPath(ovalInRect: CGRect(origin: CGPoint.zero, size: size)) 
     rectPath.appendPath(circlePath) 
     rectPath.usesEvenOddFillRule = true 
     rectPath.fill() 

     let result = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 

     return result 
    } 

} 

Kullanımı:

UIImageView:

@IBDesignable class CircularImageView: UIImageView { 

    override var image: UIImage? { 
     didSet { 
      super.image = image?.circularImage(size: nil) 
     } 
    } 

} 

UIButton:

@IBDesignable class CircularImageButton: UIButton { 

    override func setImage(image: UIImage?, forState state: UIControlState) { 
     let circularImage = image?.circularImage(size: nil) 
     super.setImage(circularImage, forState: state) 
    } 

} 
+0

Bu cevap harika çalışıyor. – AechoLiu

+0

cevabınız benim için en iyisi, teşekkürler. –

+0

"contentMode = .scaleAspectFit" ile UIImageView için daire resmi ayarlamam gerekiyor ve bu yanıt harika çalışıyor – Yaiba

1

Xcode 8.1, Swift 3.0.1

aşağıdaki gibi görünecektir Kodum:

let image = yourImage.resize(CGSize(width: 20, height: 20))?.circled(forRadius: 20) 

sonra, UIImage Uzantısı Ekleme:

func resize(_ size: CGSize) -> UIImage? { 
    let rect = CGRect(origin: .zero, size: size) 
    return redraw(in: rect) 
} 

func redraw(in rect: CGRect) -> UIImage? { 
    UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.main.scale) 

    guard let context = UIGraphicsGetCurrentContext(), let cgImage = cgImage else { return nil } 

    let rect = CGRect(origin: .zero, size: size) 
    let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: rect.size.height) 

    context.concatenate(flipVertical) 
    context.draw(cgImage, in: rect) 

    let image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
    return image 
} 

func circled(forRadius radius: CGFloat) -> UIImage? { 
    let rediusSize = CGSize(width: radius, height: radius) 
    let rect = CGRect(origin: .zero, size: size) 

    UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale) 

    guard let context = UIGraphicsGetCurrentContext(), let cgImage = cgImage else { return nil } 

    let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: rect.size.height) 
    context.concatenate(flipVertical) 

    let bezierPath = UIBezierPath(roundedRect: rect, byRoundingCorners: [.allCorners], cornerRadii: rediusSize) 
    context.addPath(bezierPath.cgPath) 
    context.clip() 

    context.drawPath(using: .fillStroke) 
    context.draw(cgImage, in: rect) 

    let image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    return image 
} 
+0

Görüntüyü daire şeklinde kırpmak için kod yazıyordum Ve bunu en iyi şekilde yanıtladım !, Ama bir sorun var Tersine çevirmek nasıl tersine çevrildi? – Salah

+0

Yardım edebilir misiniz? – Salah

+0

Merhaba @Salah, Önceki yöntemlerimin bazı sorunları olduğu için üzgünüm. Bunu şimdi kodumda düzelttim ve deneyebilirsiniz! Ama ben 'circled (:) 'metodunu yazmam gerekse de nadiren kullanırım. Çoğunlukla 'resize' +' fill (with:) 'metodları benim varlık görüntülerini kontrol etmeme yardımcı olur ve 'Kingfisher'ı tavsiye ederim, o' RoundCornerImageProcessor'unu görüntü kırpma fonksiyonunu yapmak için sağlaması gerekir. Bunu burada görebilirsiniz (https://github.com/onevcat/Kingfisher/blob/master/Sources/ImageProcessor.swift)]. – Arco

0

harici dosyası oluşturmak

extension UIImage { 
func circleImage(_ cornerRadius: CGFloat, size: CGSize) -> UIImage? { 
    let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) 
    UIGraphicsBeginImageContextWithOptions(size, false, 0) 
    if let context = UIGraphicsGetCurrentContext() { 
     var path: UIBezierPath 
     if size.height == size.width { 
      if cornerRadius == size.width/2 { 
       path = UIBezierPath(arcCenter: CGPoint(x: size.width/2, y: size.height/2), radius: cornerRadius, startAngle: 0, endAngle: 2.0*CGFloat(Double.pi), clockwise: true) 
      }else { 
       path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius) 
      } 
     }else { 
      path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius) 
     } 
     context.addPath(path.cgPath) 
     context.clip() 
     self.draw(in: rect) 
     // 从上下文上获取剪裁后的照片 
     guard let uncompressedImage = UIGraphicsGetImageFromCurrentImageContext() else { 
      UIGraphicsEndImageContext() 
      return nil 
     } 
     // 关闭上下文 
     UIGraphicsEndImageContext() 
     return uncompressedImage 
    }else { 
     return nil 
    } 
}} 
0

hızlı 3 MVC deseni uygun daire Image için bu kodu kullanabilirsiniz

@IBDesignable 
class RoundImage: UIImageView{ 


@IBInspectable var cornerRadius: CGFloat = 0 { 
    didSet{ 
     self.layer.cornerRadius = cornerRadius 
    } 
} 

// set border width 
@IBInspectable var borderWidth: CGFloat = 0 { 
    didSet{ 
     self.layer.borderWidth = borderWidth 
    } 
} 

// set border color 

@IBInspectable var borderColor: UIColor = UIColor.clear { 
    didSet{ 
     self.layer.borderColor = borderColor.cgColor 
    } 
} 

override func awakeFromNib() { 
    self.clipsToBounds = true 
} 


}// class 

film şeridindeki IB sınıfında

çağrı sınıfı Eğer lütfen (genişliğin 1/2 arzu daire ise)

set attribute

Yapıldı olarak

call class in the IB on storyboard

seti CornerRadius!