Ver código fonte

Introduced a 'backgroundColor' property to the RoundCornerImageProcessor allowing to specify a desired backgroud color for the output image

Sebastian Crow 8 anos atrás
pai
commit
24433fda45
2 arquivos alterados com 47 adições e 18 exclusões
  1. 19 4
      Sources/Image.swift
  2. 28 14
      Sources/ImageProcessor.swift

+ 19 - 4
Sources/Image.swift

@@ -340,16 +340,18 @@ extension Kingfisher where Base: Image {
     // MARK: - Round Corner
     // MARK: - Round Corner
     /// Create a round corner image based on `self`.
     /// 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`.
     /// - returns: An image with round corner of `self`.
     ///
     ///
     /// - Note: This method only works for CG-based image.
     /// - Note: This method only works for CG-based image.
     public func image(withRoundRadius radius: CGFloat,
     public func image(withRoundRadius radius: CGFloat,
                       fit size: CGSize,
                       fit size: CGSize,
-                      roundingCorners corners: RectCorner = .all) -> Image
+                      roundingCorners corners: RectCorner = .all,
+                      backgroundColor: Color? = nil) -> Image
     {   
     {   
         guard let cgImage = cgImage else {
         guard let cgImage = cgImage else {
             assertionFailure("[Kingfisher] Round corner image only works for CG-based image.")
             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)
         let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: size)
         return draw(cgImage: cgImage, to: size) {
         return draw(cgImage: cgImage, to: size) {
             #if os(macOS)
             #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)
                 let path = NSBezierPath(roundedRect: rect, byRoundingCorners: corners, radius: radius)
                 path.windingRule = .evenOddWindingRule
                 path.windingRule = .evenOddWindingRule
                 path.addClip()
                 path.addClip()
@@ -368,6 +376,13 @@ extension Kingfisher where Base: Image {
                     assertionFailure("[Kingfisher] Failed to create CG context for image.")
                     assertionFailure("[Kingfisher] Failed to create CG context for image.")
                     return
                     return
                 }
                 }
+
+                if let backgroundColor = backgroundColor {
+                    let rectPath = UIBezierPath(rect: rect)
+                    backgroundColor.setFill()
+                    rectPath.fill()
+                }
+
                 let path = UIBezierPath(roundedRect: rect,
                 let path = UIBezierPath(roundedRect: rect,
                                         byRoundingCorners: corners.uiRectCorner,
                                         byRoundingCorners: corners.uiRectCorner,
                                         cornerRadii: CGSize(width: radius, height: radius)).cgPath
                                         cornerRadii: CGSize(width: radius, height: radius)).cgPath

+ 28 - 14
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.
     /// Target size of output image should be. If `nil`, the image will keep its original size after processing.
     public let targetSize: CGSize?
     public let targetSize: CGSize?
-    
+
+    /// Background color of the output image. If `nil`, it will stay transparent.
+    public let backgroundColor: Color?
+
     /// Initialize a `RoundCornerImageProcessor`
     /// 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.cornerRadius = cornerRadius
         self.targetSize = targetSize
         self.targetSize = targetSize
         self.roundingCorners = corners
         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.
     /// Process an input `ImageProcessItem` item to an image for this processor.
@@ -208,7 +222,7 @@ public struct RoundCornerImageProcessor: ImageProcessor {
         switch item {
         switch item {
         case .image(let image):
         case .image(let image):
             let size = targetSize ?? image.kf.size
             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(_):
         case .data(_):
             return (DefaultImageProcessor.default >> self).process(item: item, options: options)
             return (DefaultImageProcessor.default >> self).process(item: item, options: options)
         }
         }