Browse Source

Merge pull request #814 from onevcat/fix/processor-scale

Apply scale on all image based processor methods
Wei Wang 8 years ago
parent
commit
5a33b593f4
3 changed files with 56 additions and 8 deletions
  1. 15 0
      Sources/Image.swift
  2. 15 8
      Sources/ImageProcessor.swift
  3. 26 0
      Tests/KingfisherTests/ImageProcessorTests.swift

+ 15 - 0
Sources/Image.swift

@@ -626,6 +626,21 @@ extension Kingfisher where Base: Image {
             return apply(.colorControl((brightness, contrast, saturation, inputEV)))
         #endif
     }
+
+    /// Return an image with given scale.
+    ///
+    /// - Parameter scale: Target scale factor the new image should have.
+    /// - Returns: The image with target scale. If the base image is already in the scale, `base` will be returned.
+    public func scaled(to scale: CGFloat) -> Image {
+        guard scale != self.scale else {
+            return base
+        }
+        guard let cgImage = cgImage else {
+            assertionFailure("[Kingfisher] Scaling only works for CG-based image.")
+            return base
+        }
+        return Kingfisher.image(cgImage: cgImage, scale: scale, refImage: base)
+    }
 }
 
 // MARK: - Decode

+ 15 - 8
Sources/ImageProcessor.swift

@@ -129,7 +129,7 @@ public struct DefaultImageProcessor: ImageProcessor {
     public func process(item: ImageProcessItem, options: KingfisherOptionsInfo) -> Image? {
         switch item {
         case .image(let image):
-            return image
+            return image.kf.scaled(to: options.scaleFactor)
         case .data(let data):
             return Kingfisher<Image>.image(
                 data: data,
@@ -222,7 +222,8 @@ 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, backgroundColor: backgroundColor)
+            return image.kf.scaled(to: options.scaleFactor)
+                        .kf.image(withRoundRadius: cornerRadius, fit: size, roundingCorners: roundingCorners, backgroundColor: backgroundColor)
         case .data(_):
             return (DefaultImageProcessor.default >> self).process(item: item, options: options)
         }
@@ -296,7 +297,8 @@ public struct ResizingImageProcessor: ImageProcessor {
     public func process(item: ImageProcessItem, options: KingfisherOptionsInfo) -> Image? {
         switch item {
         case .image(let image):
-            return image.kf.resize(to: referenceSize, for: targetContentMode)
+            return image.kf.scaled(to: options.scaleFactor)
+                        .kf.resize(to: referenceSize, for: targetContentMode)
         case .data(_):
             return (DefaultImageProcessor.default >> self).process(item: item, options: options)
         }
@@ -334,7 +336,8 @@ public struct BlurImageProcessor: ImageProcessor {
         switch item {
         case .image(let image):
             let radius = blurRadius * options.scaleFactor
-            return image.kf.blurred(withRadius: radius)
+            return image.kf.scaled(to: options.scaleFactor)
+                        .kf.blurred(withRadius: radius)
         case .data(_):
             return (DefaultImageProcessor.default >> self).process(item: item, options: options)
         }
@@ -376,7 +379,8 @@ public struct OverlayImageProcessor: ImageProcessor {
     public func process(item: ImageProcessItem, options: KingfisherOptionsInfo) -> Image? {
         switch item {
         case .image(let image):
-            return image.kf.overlaying(with: overlay, fraction: fraction)
+            return image.kf.scaled(to: options.scaleFactor)
+                        .kf.overlaying(with: overlay, fraction: fraction)
         case .data(_):
             return (DefaultImageProcessor.default >> self).process(item: item, options: options)
         }
@@ -412,7 +416,8 @@ public struct TintImageProcessor: ImageProcessor {
     public func process(item: ImageProcessItem, options: KingfisherOptionsInfo) -> Image? {
         switch item {
         case .image(let image):
-            return image.kf.tinted(with: tint)
+            return image.kf.scaled(to: options.scaleFactor)
+                        .kf.tinted(with: tint)
         case .data(_):
             return (DefaultImageProcessor.default >> self).process(item: item, options: options)
         }
@@ -464,7 +469,8 @@ public struct ColorControlsProcessor: ImageProcessor {
     public func process(item: ImageProcessItem, options: KingfisherOptionsInfo) -> Image? {
         switch item {
         case .image(let image):
-            return image.kf.adjusted(brightness: brightness, contrast: contrast, saturation: saturation, inputEV: inputEV)
+            return image.kf.scaled(to: options.scaleFactor)
+                        .kf.adjusted(brightness: brightness, contrast: contrast, saturation: saturation, inputEV: inputEV)
         case .data(_):
             return (DefaultImageProcessor.default >> self).process(item: item, options: options)
         }
@@ -549,7 +555,8 @@ public struct CroppingImageProcessor: ImageProcessor {
     public func process(item: ImageProcessItem, options: KingfisherOptionsInfo) -> Image? {
         switch item {
         case .image(let image):
-            return image.kf.crop(to: size, anchorOn: anchor)
+            return image.kf.scaled(to: options.scaleFactor)
+                        .kf.crop(to: size, anchorOn: anchor)
         case .data(_): return (DefaultImageProcessor.default >> self).process(item: item, options: options)
         }
     }

+ 26 - 0
Tests/KingfisherTests/ImageProcessorTests.swift

@@ -152,6 +152,32 @@ class ImageProcessorTests: XCTestCase {
         XCTAssertEqual(p.identifier, "com.onevcat.Kingfisher.CroppingImageProcessor((50.0, 50.0)_(0.5, 0.5))")
         checkProcessor(p, with: "cropping-50-50-anchor-center")
     }
+
+    #if os(iOS) || os(tvOS)
+    func testImageProcessorRespectOptionScale() {
+        let image = testImage
+        XCTAssertEqual(image.scale, 1.0)
+
+        let size = CGSize(width: 2, height: 2)
+
+        let processors: [ImageProcessor] = [
+            DefaultImageProcessor(),
+            RoundCornerImageProcessor(cornerRadius: 1.0, targetSize: size),
+            ResizingImageProcessor(referenceSize: size),
+            BlurImageProcessor(blurRadius: 1.0),
+            OverlayImageProcessor(overlay: .red),
+            TintImageProcessor(tint: .red),
+            ColorControlsProcessor(brightness: 0, contrast: 0, saturation: 0, inputEV: 0),
+            BlackWhiteProcessor(),
+            CroppingImageProcessor(size: size)
+        ]
+
+        let images = processors.map { $0.process(item: .image(image), options: [.scaleFactor(2.0)]) }
+        images.forEach {
+            XCTAssertEqual($0!.scale, 2.0)
+        }
+    }
+    #endif
 }
 
 struct TestCIImageProcessor: CIImageProcessor {