Resize the GIF with aspect ratio

We can use the contentMode of the UIImageView to resize the GIF keeping
the aspect ratio if the content mode is set to do so.
This commit is contained in:
Tony DiPasquale 2015-04-23 18:55:40 -04:00
parent 87517a5b8b
commit ccf049f87a
3 changed files with 21 additions and 9 deletions

View File

@ -1,6 +1,7 @@
/// Protocol that requires its members to have a `layer` and a `frame` property. /// Protocol that requires its members to have a `layer`, `frame`, and `contentMode` property.
/// Classes confirming to this protocol can serve as a delegate to `Animator`. /// Classes confirming to this protocol can serve as a delegate to `Animator`.
protocol Animatable { protocol Animatable {
var layer: CALayer { get } var layer: CALayer { get }
var frame: CGRect { get } var frame: CGRect { get }
var contentMode: UIViewContentMode { get }
} }

View File

@ -57,8 +57,17 @@ class Animator: NSObject {
let frameDuration = CGImageSourceGIFFrameDuration(imageSource, index) let frameDuration = CGImageSourceGIFFrameDuration(imageSource, index)
let frameImageRef = CGImageSourceCreateImageAtIndex(imageSource, index, nil) let frameImageRef = CGImageSourceCreateImageAtIndex(imageSource, index, nil)
let frame = UIImage(CGImage: frameImageRef)?.resize(size)
let animatedFrame = AnimatedFrame(image: frame, duration: frameDuration) let image = UIImage(CGImage: frameImageRef)
let scaledImage: UIImage?
switch delegate.contentMode {
case .ScaleAspectFit: scaledImage = image?.resizeAspectFit(size)
case .ScaleAspectFill: scaledImage = image?.resizeAspectFill(size)
default: scaledImage = image?.resize(size)
}
let animatedFrame = AnimatedFrame(image: scaledImage, duration: frameDuration)
return (accumulatedFrames + [animatedFrame], accumulatedDuration + frameDuration) return (accumulatedFrames + [animatedFrame], accumulatedDuration + frameDuration)
} }

View File

@ -50,14 +50,19 @@ extension UIImage {
} }
private extension CGSize { private extension CGSize {
/// Calculates the aspect ratio of the size.
///
/// :returns: aspectRatio The aspect ratio of the size.
var aspectRatio: CGFloat {
if height == 0 { return 1 }
return width / height
}
/// Finds a new size constrained by a size keeping the aspect ratio. /// Finds a new size constrained by a size keeping the aspect ratio.
/// ///
/// :param: size The contraining size. /// :param: size The contraining size.
/// :returns: size A new size that fits inside the contraining size with the same aspect ratio. /// :returns: size A new size that fits inside the contraining size with the same aspect ratio.
func sizeConstrainedBySize(size: CGSize) -> CGSize { func sizeConstrainedBySize(size: CGSize) -> CGSize {
if height == 0 { return size }
let aspectRatio = width / height
let aspectWidth = round(aspectRatio * size.height) let aspectWidth = round(aspectRatio * size.height)
let aspectHeight = round(size.width / aspectRatio) let aspectHeight = round(size.width / aspectRatio)
@ -73,9 +78,6 @@ private extension CGSize {
/// :param: size The contraining size. /// :param: size The contraining size.
/// :returns: size A new size that fills the contraining size keeping the same aspect ratio. /// :returns: size A new size that fills the contraining size keeping the same aspect ratio.
func sizeFillingSize(size: CGSize) -> CGSize { func sizeFillingSize(size: CGSize) -> CGSize {
if height == 0 { return size }
let aspectRatio = width / height
let aspectWidth = round(aspectRatio * size.height) let aspectWidth = round(aspectRatio * size.height)
let aspectHeight = round(size.width / aspectRatio) let aspectHeight = round(size.width / aspectRatio)