|
|
@@ -290,21 +290,22 @@ extension KingfisherWrapper where Base: KFCrossPlatformImage {
|
|
|
|
|
|
return vImage_Buffer(data: data, height: height, width: width, rowBytes: rowBytes)
|
|
|
}
|
|
|
-
|
|
|
- guard let context = beginContext(size: size, scale: scale, inverting: true) else {
|
|
|
+ GraphicsContext.begin(size: size, scale: scale)
|
|
|
+ guard let context = GraphicsContext.current(size: size, scale: scale, inverting: true, cgImage: cgImage) else {
|
|
|
assertionFailure("[Kingfisher] Failed to create CG context for blurring image.")
|
|
|
return base
|
|
|
}
|
|
|
context.draw(cgImage, in: CGRect(x: 0, y: 0, width: w, height: h))
|
|
|
- endContext()
|
|
|
+ GraphicsContext.end()
|
|
|
|
|
|
var inBuffer = createEffectBuffer(context)
|
|
|
|
|
|
- guard let outContext = beginContext(size: size, scale: scale, inverting: true) else {
|
|
|
+ GraphicsContext.begin(size: size, scale: scale)
|
|
|
+ guard let outContext = GraphicsContext.current(size: size, scale: scale, inverting: true, cgImage: cgImage) else {
|
|
|
assertionFailure("[Kingfisher] Failed to create CG context for blurring image.")
|
|
|
return base
|
|
|
}
|
|
|
- defer { endContext() }
|
|
|
+ defer { GraphicsContext.end() }
|
|
|
var outBuffer = createEffectBuffer(outContext)
|
|
|
|
|
|
for _ in 0 ..< iterations {
|
|
|
@@ -457,55 +458,42 @@ extension KingfisherWrapper where Base: KFCrossPlatformImage {
|
|
|
return true
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-extension KingfisherWrapper where Base: KFCrossPlatformImage {
|
|
|
-
|
|
|
- func beginContext(size: CGSize, scale: CGFloat, inverting: Bool = false) -> CGContext? {
|
|
|
- #if os(macOS)
|
|
|
- guard let rep = NSBitmapImageRep(
|
|
|
- bitmapDataPlanes: nil,
|
|
|
- pixelsWide: Int(size.width),
|
|
|
- pixelsHigh: Int(size.height),
|
|
|
- bitsPerSample: cgImage?.bitsPerComponent ?? 8,
|
|
|
- samplesPerPixel: 4,
|
|
|
- hasAlpha: true,
|
|
|
- isPlanar: false,
|
|
|
- colorSpaceName: .calibratedRGB,
|
|
|
- bytesPerRow: 0,
|
|
|
- bitsPerPixel: 0) else
|
|
|
- {
|
|
|
- assertionFailure("[Kingfisher] Image representation cannot be created.")
|
|
|
- return nil
|
|
|
- }
|
|
|
- rep.size = size
|
|
|
- NSGraphicsContext.saveGraphicsState()
|
|
|
- guard let context = NSGraphicsContext(bitmapImageRep: rep) else {
|
|
|
- assertionFailure("[Kingfisher] Image context cannot be created.")
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- NSGraphicsContext.current = context
|
|
|
- return context.cgContext
|
|
|
- #else
|
|
|
- UIGraphicsBeginImageContextWithOptions(size, false, scale)
|
|
|
- guard let context = UIGraphicsGetCurrentContext() else { return nil }
|
|
|
- if inverting { // If drawing a CGImage, we need to make context flipped.
|
|
|
- context.scaleBy(x: 1.0, y: -1.0)
|
|
|
- context.translateBy(x: 0, y: -size.height)
|
|
|
- }
|
|
|
- return context
|
|
|
- #endif
|
|
|
- }
|
|
|
-
|
|
|
- func endContext() {
|
|
|
- #if os(macOS)
|
|
|
- NSGraphicsContext.restoreGraphicsState()
|
|
|
+ /// Returns decoded image of the `base` image at a given scale. It will draw the image in a plain context and
|
|
|
+ /// return the data from it. This could improve the drawing performance when an image is just created from
|
|
|
+ /// data but not yet displayed for the first time.
|
|
|
+ ///
|
|
|
+ /// - Parameter context: The context for frawing.
|
|
|
+ /// - Returns: The decoded image ready to be displayed.
|
|
|
+ ///
|
|
|
+ /// - Note: This method only works for CG-based image. The current image scale is kept.
|
|
|
+ /// For any non-CG-based image or animated image, `base` itself is returned.
|
|
|
+ public func decoded(on context: CGContext) -> KFCrossPlatformImage {
|
|
|
+ // Prevent animated image (GIF) losing it's images
|
|
|
+ #if os(iOS)
|
|
|
+ if imageSource != nil { return base }
|
|
|
#else
|
|
|
- UIGraphicsEndImageContext()
|
|
|
+ if images != nil { return base }
|
|
|
#endif
|
|
|
+
|
|
|
+ guard let refImage = cgImage else {
|
|
|
+ assertionFailure("[Kingfisher] Decoding only works for CG-based image.")
|
|
|
+ return base
|
|
|
+ }
|
|
|
+
|
|
|
+ let size = CGSize(width: CGFloat(refImage.width) / scale, height: CGFloat(refImage.height) / scale)
|
|
|
+
|
|
|
+ context.draw(refImage, in: CGRect(origin: .zero, size: size))
|
|
|
+
|
|
|
+ guard let cgImage = context.makeImage() else {
|
|
|
+ return base
|
|
|
+ }
|
|
|
+
|
|
|
+ return KingfisherWrapper.image(cgImage: cgImage, scale: scale, refImage: base)
|
|
|
}
|
|
|
-
|
|
|
+}
|
|
|
+
|
|
|
+extension KingfisherWrapper where Base: KFCrossPlatformImage {
|
|
|
func draw(
|
|
|
to size: CGSize,
|
|
|
inverting: Bool = false,
|
|
|
@@ -515,11 +503,12 @@ extension KingfisherWrapper where Base: KFCrossPlatformImage {
|
|
|
) -> KFCrossPlatformImage
|
|
|
{
|
|
|
let targetScale = scale ?? self.scale
|
|
|
- guard let context = beginContext(size: size, scale: targetScale, inverting: inverting) else {
|
|
|
+ GraphicsContext.begin(size: size, scale: targetScale)
|
|
|
+ guard let context = GraphicsContext.current(size: size, scale: targetScale, inverting: inverting, cgImage: cgImage) else {
|
|
|
assertionFailure("[Kingfisher] Failed to create CG context for blurring image.")
|
|
|
return base
|
|
|
}
|
|
|
- defer { endContext() }
|
|
|
+ defer { GraphicsContext.end() }
|
|
|
let useRefImage = draw(context)
|
|
|
guard let cgImage = context.makeImage() else {
|
|
|
return base
|