Skip to content

Commit

Permalink
Merge pull request #2357 from yeatse/animated-frames-performance
Browse files Browse the repository at this point in the history
Resolves performance issue when presenting animated images
  • Loading branch information
onevcat authored Feb 4, 2025
2 parents 8995a41 + 7c36093 commit 80b4f26
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
18 changes: 18 additions & 0 deletions Sources/Image/GIFAnimatedImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ public protocol ImageFrameSource {

/// Retrieves the duration at a specific index. If the index is invalid, implementors should return `0.0`.
func duration(at index: Int) -> TimeInterval

/// Creates a copy of the current `ImageFrameSource` instance.
///
/// - Returns: A new instance of the same type as `self` with identical properties.
/// If not overridden by conforming types, this default implementation
/// simply returns `self`, which may not create an actual copy if the type is a reference type.
func copy() -> Self
}

public extension ImageFrameSource {
Expand All @@ -156,6 +163,10 @@ public extension ImageFrameSource {
func frame(at index: Int) -> CGImage? {
return frame(at: index, maxSize: nil)
}

func copy() -> Self {
return self
}
}

struct CGImageFrameSource: ImageFrameSource {
Expand Down Expand Up @@ -183,5 +194,12 @@ struct CGImageFrameSource: ImageFrameSource {
func duration(at index: Int) -> TimeInterval {
return GIFAnimatedImage.getFrameDuration(from: imageSource, at: index)
}

func copy() -> Self {
guard let data = data, let source = CGImageSourceCreateWithData(data as CFData, options as CFDictionary?) else {
return self
}
return CGImageFrameSource(data: data, imageSource: source, options: options)
}
}

4 changes: 2 additions & 2 deletions Sources/Views/AnimatedImageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ extension AnimatedImageView {
framePreloadCount count: Int,
repeatCount: RepeatCount,
preloadQueue: DispatchQueue) {
self.frameSource = source
self.frameSource = source.copy()
self.contentMode = mode
self.size = size
self.imageSize = imageSize
Expand Down Expand Up @@ -741,7 +741,7 @@ extension AnimatedImageView {
return KFCrossPlatformImage(cgImage: cgImage)
}

return KFCrossPlatformImage(cgImage: unretainedImage)
return KFCrossPlatformImage(cgImage: unretainedImage).preparingForDisplay()
} else {
return KFCrossPlatformImage(cgImage: cgImage)
}
Expand Down

0 comments on commit 80b4f26

Please sign in to comment.