From 0a7cb18e8353026fcd93cf133a72ddcb323b3ea2 Mon Sep 17 00:00:00 2001 From: Sebastian Crow Date: Sat, 9 Sep 2017 23:22:17 +0200 Subject: [PATCH] Introduced a 'backgroundColor' property to the RoundCornerImageProcessor allowing to specify a desired backgroud color for the output image --- Sources/Image.swift | 23 ++++++++++++++++---- Sources/ImageProcessor.swift | 42 ++++++++++++++++++++++++------------ 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/Sources/Image.swift b/Sources/Image.swift index 22c3e1f93..f9005bd1f 100755 --- a/Sources/Image.swift +++ b/Sources/Image.swift @@ -340,16 +340,18 @@ extension Kingfisher where Base: Image { // MARK: - Round Corner /// Create a round corner image based on `self`. /// - /// - parameter radius: The round corner radius of creating image. - /// - parameter size: The target size of creating image. - /// - parameter corners: The target corners which will be applied rounding. + /// - parameter radius: The round corner radius of creating image. + /// - parameter size: The target size of creating image. + /// - parameter corners: The target corners which will be applied rounding. + /// - parameter backgroundColor: The background color for the output image /// /// - returns: An image with round corner of `self`. /// /// - Note: This method only works for CG-based image. public func image(withRoundRadius radius: CGFloat, fit size: CGSize, - roundingCorners corners: RectCorner = .all) -> Image + roundingCorners corners: RectCorner = .all, + backgroundColor: Color? = nil) -> Image { guard let cgImage = cgImage else { assertionFailure("[Kingfisher] Round corner image only works for CG-based image.") @@ -359,6 +361,12 @@ extension Kingfisher where Base: Image { let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: size) return draw(cgImage: cgImage, to: size) { #if os(macOS) + if let backgroundColor = backgroundColor { + let rectPath = NSBezierPath(rect: rect) + backgroundColor.setFill() + rectPath.fill() + } + let path = NSBezierPath(roundedRect: rect, byRoundingCorners: corners, radius: radius) path.windingRule = .evenOddWindingRule path.addClip() @@ -368,6 +376,13 @@ extension Kingfisher where Base: Image { assertionFailure("[Kingfisher] Failed to create CG context for image.") return } + + if let backgroundColor = backgroundColor { + let rectPath = UIBezierPath(rect: rect) + backgroundColor.setFill() + rectPath.fill() + } + let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners.uiRectCorner, cornerRadii: CGSize(width: radius, height: radius)).cgPath diff --git a/Sources/ImageProcessor.swift b/Sources/ImageProcessor.swift index 2d02256d3..782c94b8c 100644 --- a/Sources/ImageProcessor.swift +++ b/Sources/ImageProcessor.swift @@ -176,24 +176,38 @@ public struct RoundCornerImageProcessor: ImageProcessor { /// Target size of output image should be. If `nil`, the image will keep its original size after processing. public let targetSize: CGSize? - + + /// Background color of the output image. If `nil`, it will stay transparent. + public let backgroundColor: Color? + /// Initialize a `RoundCornerImageProcessor` /// - /// - parameter cornerRadius: Corner radius will be applied in processing. - /// - parameter targetSize: Target size of output image should be. If `nil`, - /// the image will keep its original size after processing. - /// Default is `nil`. - /// - parameter corners: The target corners which will be applied rounding. Default is `.all`. - public init(cornerRadius: CGFloat, targetSize: CGSize? = nil, roundingCorners corners: RectCorner = .all) { + /// - parameter cornerRadius: Corner radius will be applied in processing. + /// - parameter targetSize: Target size of output image should be. If `nil`, + /// the image will keep its original size after processing. + /// Default is `nil`. + /// - parameter corners: The target corners which will be applied rounding. Default is `.all`. + /// - parameter backgroundColor: Backgroud color to apply for the output image. Default is `nil`. + public init(cornerRadius: CGFloat, targetSize: CGSize? = nil, roundingCorners corners: RectCorner = .all, backgroundColor: Color? = nil) { self.cornerRadius = cornerRadius self.targetSize = targetSize self.roundingCorners = corners - - if let size = targetSize { - self.identifier = "com.onevcat.Kingfisher.RoundCornerImageProcessor(\(cornerRadius)_\(size)\(corners.cornerIdentifier))" - } else { - self.identifier = "com.onevcat.Kingfisher.RoundCornerImageProcessor(\(cornerRadius)\(corners.cornerIdentifier))" - } + self.backgroundColor = backgroundColor + + self.identifier = { + var identifier = "" + + if let size = targetSize { + identifier = "com.onevcat.Kingfisher.RoundCornerImageProcessor(\(cornerRadius)_\(size)\(corners.cornerIdentifier))" + } else { + identifier = "com.onevcat.Kingfisher.RoundCornerImageProcessor(\(cornerRadius)\(corners.cornerIdentifier))" + } + if let backgroundColor = backgroundColor { + identifier += "_\(backgroundColor)" + } + + return identifier + }() } /// Process an input `ImageProcessItem` item to an image for this processor. @@ -208,7 +222,7 @@ public struct RoundCornerImageProcessor: ImageProcessor { switch item { case .image(let image): let size = targetSize ?? image.kf.size - return image.kf.image(withRoundRadius: cornerRadius, fit: size, roundingCorners: roundingCorners) + return image.kf.image(withRoundRadius: cornerRadius, fit: size, roundingCorners: roundingCorners, backgroundColor: backgroundColor) case .data(_): return (DefaultImageProcessor.default >> self).process(item: item, options: options) }