Skip to content

Commit

Permalink
Modify Project to UIImage and UIImageView extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
王佳玮 authored and 王佳玮 committed Mar 14, 2016
1 parent 0ad1527 commit 951bb33
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 58 deletions.
11 changes: 5 additions & 6 deletions Example/JWAnimatedImageExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
objects = {

/* Begin PBXBuildFile section */
280039361C96ED3E0089D73C /* JWAnimatedImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 280039341C96ECCB0089D73C /* JWAnimatedImage.framework */; };
280039371C96ED3E0089D73C /* JWAnimatedImage.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 280039341C96ECCB0089D73C /* JWAnimatedImage.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
280E30A21C8AE028002ACA3D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280E30A11C8AE028002ACA3D /* AppDelegate.swift */; };
280E30A41C8AE028002ACA3D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280E30A31C8AE028002ACA3D /* ViewController.swift */; };
280E30A71C8AE028002ACA3D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 280E30A51C8AE028002ACA3D /* Main.storyboard */; };
280E30A91C8AE028002ACA3D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 280E30A81C8AE028002ACA3D /* Assets.xcassets */; };
280E30AC1C8AE028002ACA3D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 280E30AA1C8AE028002ACA3D /* LaunchScreen.storyboard */; };
28744EC51C8D81D900C40C3C /* JWAnimatedImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28744EC41C8D81D900C40C3C /* JWAnimatedImage.framework */; };
28744EC61C8D81D900C40C3C /* JWAnimatedImage.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 28744EC41C8D81D900C40C3C /* JWAnimatedImage.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
28B608C41C8AE0E400AE39A1 /* test.gif in Resources */ = {isa = PBXBuildFile; fileRef = 28B608C31C8AE0E400AE39A1 /* test.gif */; };
/* End PBXBuildFile section */

Expand All @@ -24,22 +24,22 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
28744EC61C8D81D900C40C3C /* JWAnimatedImage.framework in Embed Frameworks */,
280039371C96ED3E0089D73C /* JWAnimatedImage.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
280039341C96ECCB0089D73C /* JWAnimatedImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JWAnimatedImage.framework; path = "/Users/wangjwchn/Library/Developer/Xcode/DerivedData/JWAnimatedImage-eownceceuuqcdaanyxpugfmbcdxf/Build/Products/Debug-iphoneos/JWAnimatedImage.framework"; sourceTree = "<absolute>"; };
280E309E1C8AE028002ACA3D /* JWAnimatedImageExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JWAnimatedImageExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
280E30A11C8AE028002ACA3D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
280E30A31C8AE028002ACA3D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
280E30A61C8AE028002ACA3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
280E30A81C8AE028002ACA3D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
280E30AB1C8AE028002ACA3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
280E30AD1C8AE028002ACA3D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
28744EC41C8D81D900C40C3C /* JWAnimatedImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = JWAnimatedImage.framework; path = "/Users/wangjwchn/Library/Developer/Xcode/DerivedData/JWAnimatedImage-etvijfdcsutceodtmheqhucdtmqb/Build/Products/Debug-iphoneos/JWAnimatedImage.framework"; sourceTree = "<absolute>"; };
28B608C31C8AE0E400AE39A1 /* test.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = test.gif; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand All @@ -48,7 +48,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
28744EC51C8D81D900C40C3C /* JWAnimatedImage.framework in Frameworks */,
280039361C96ED3E0089D73C /* JWAnimatedImage.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -58,7 +58,6 @@
280E30951C8AE028002ACA3D = {
isa = PBXGroup;
children = (
28744EC41C8D81D900C40C3C /* JWAnimatedImage.framework */,
280E30A01C8AE028002ACA3D /* JWAnimatedImageExample */,
280E309F1C8AE028002ACA3D /* Products */,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8150" systemVersion="15A204g" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9532" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8122"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9530"/>
</dependencies>
<scenes>
<!--View Controller-->
Expand All @@ -15,7 +16,6 @@
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
Expand Down
22 changes: 6 additions & 16 deletions Example/JWAnimatedImageExample/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,13 @@ class ViewController: UIViewController {
super.viewDidLoad()
let imageData = NSData(contentsOfURL:NSBundle.mainBundle().URLForResource("test", withExtension: "gif")!)

//one GIF image
let imageView = JWAnimatedImageView()
imageView.addGifImage(imageData!)
imageView.frame = CGRect(x: 7.0, y: 50.0, width: 400.0, height: 224.0)
view.addSubview(imageView)
let image = UIImage()
image.AddGifFromData(imageData!)
let imageview = UIImageView()
imageview.AddGifImage(image)
imageview.frame = CGRect(x: 7.0, y: 50.0, width: 400.0, height: 224.0)
view.addSubview(imageview)

//30 GIF images
/*
for i in 0..<3 {
for j in 0..<10 {
let imageView = JWAnimatedImageView()
imageView.addGifImage(imageData!)
imageView.frame = CGRect(x: 0.0+Double(100*i), y:50.0+Double(56*j), width: 100.0, height: 56.0)
view.addSubview(imageView)
}
}
*/
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
Expand Down
12 changes: 8 additions & 4 deletions JWAnimatedImage.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
objects = {

/* Begin PBXBuildFile section */
280E30221C8AD9B1002ACA3D /* JWAnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280E30211C8AD9B1002ACA3D /* JWAnimatedImageView.swift */; };
2800392C1C96EC640089D73C /* JWAnimatedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2800392A1C96EC640089D73C /* JWAnimatedImage.swift */; };
2800392D1C96EC640089D73C /* JWAnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2800392B1C96EC640089D73C /* JWAnimatedImageView.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
2800392A1C96EC640089D73C /* JWAnimatedImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JWAnimatedImage.swift; sourceTree = "<group>"; };
2800392B1C96EC640089D73C /* JWAnimatedImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JWAnimatedImageView.swift; sourceTree = "<group>"; };
280E30161C8AD8CF002ACA3D /* JWAnimatedImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = JWAnimatedImage.framework; sourceTree = BUILT_PRODUCTS_DIR; };
280E301B1C8AD8CF002ACA3D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
280E30211C8AD9B1002ACA3D /* JWAnimatedImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JWAnimatedImageView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -46,7 +48,8 @@
280E30181C8AD8CF002ACA3D /* JWAnimatedImage */ = {
isa = PBXGroup;
children = (
280E30211C8AD9B1002ACA3D /* JWAnimatedImageView.swift */,
2800392A1C96EC640089D73C /* JWAnimatedImage.swift */,
2800392B1C96EC640089D73C /* JWAnimatedImageView.swift */,
280E301B1C8AD8CF002ACA3D /* Info.plist */,
);
path = JWAnimatedImage;
Expand Down Expand Up @@ -130,7 +133,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
280E30221C8AD9B1002ACA3D /* JWAnimatedImageView.swift in Sources */,
2800392D1C96EC640089D73C /* JWAnimatedImageView.swift in Sources */,
2800392C1C96EC640089D73C /* JWAnimatedImage.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
2 changes: 1 addition & 1 deletion JWAnimatedImage/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.1.0</string>
<string>0.1.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
23 changes: 13 additions & 10 deletions JWAnimatedImage/JWAnimatedImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,19 @@ let _displayRefreshFactorKey = malloc(4)
let _imageCountKey = malloc(4)
let _displayOrderKey = malloc(4)
let _imageSizeKey = malloc(4)
extension UIImage{
public extension UIImage{

//The level of integrity of a gif image,The range is 0%(0)~100%(1).we know that CADisplayLink.frameInterval affact the display frames per second,if it is larger, we will only dispaly fewer frames per second,in the other way,we will never display some of frames all the time.So,the level of integrity gives us a limit that the device should show how many frames at least.If it is 100%(1),that means the device displays frames as much as it can.The default number is 0.8,but you can decrease it for a less cpu usage.Default is 0.8
public func AddGifFromData(gif:NSData){
AddGifFromData(gif,levelOfIntegrity: 0.8)
}

public func AddGifFromData(gif:NSData,levelOfIntegrity:Float){
imageSource = CGImageSourceCreateWithData(gif, nil)
CalculateFrameDelay(GetDelayTimes(imageSource),levelOfIntegrity: levelOfIntegrity)
CalculateFrameSize()
}

var imageSource:CGImageSource?{
get {
return (objc_getAssociatedObject(self, _imageSourceKey) as! CGImageSource)
Expand Down Expand Up @@ -60,15 +72,6 @@ extension UIImage{
}
}

func AddGifFromData(gif:NSData){
AddGifFromData(gif,levelOfIntegrity: 0.8)
}

func AddGifFromData(gif:NSData,levelOfIntegrity:Float){
imageSource = CGImageSourceCreateWithData(gif, nil)
CalculateFrameDelay(GetDelayTimes(imageSource),levelOfIntegrity: levelOfIntegrity)
CalculateFrameSize()
}
func GetDelayTimes(imageSource:CGImageSourceRef?)->[Float]{

let imageCount = CGImageSourceGetCount(imageSource!)
Expand Down
39 changes: 21 additions & 18 deletions JWAnimatedImage/JWAnimatedImageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,27 @@ let _gifImageKey = malloc(4)
let _cacheKey = malloc(4)
let _currentImageKey = malloc(4)
let _displayOrderIndexKey = malloc(4)
extension UIImageView{
public extension UIImageView{

//When the program is running,it use a strategy called 'cache or nothing'.When all frames can be put into the cache under the 'memoryLimit' restriction,it will put them all .Otherwise, we will not make any cache.After a lot of comparison,(such as,only cache part of frames,or use 'double swap memory',like the swap buffer when render layers),I think it is the best way.
public func AddGifImage(gifImage:UIImage){
AddGifImage(gifImage,memoryLimit: 20)
}

public func AddGifImage(gifImage:UIImage,memoryLimit:Int){
self.gifImage = gifImage
self.displayOrderIndex = 0
self.currentImage = UIImage(CGImage: CGImageSourceCreateImageAtIndex(self.gifImage.imageSource!,0,nil)!)
if(self.gifImage.imageSize>=memoryLimit){
self.timer = CADisplayLink(target: self, selector: Selector("updateFrameWithoutCache"))
}else{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0),prepareCache)
self.timer = CADisplayLink(target: self, selector: Selector("updateFrameWithCache"))
}
timer!.frameInterval = gifImage.displayRefreshFactor!
timer!.addToRunLoop(.mainRunLoop(), forMode: NSRunLoopCommonModes)
}

var timer:CADisplayLink?{
get {
return (objc_getAssociatedObject(self, _timerKey) as! CADisplayLink)
Expand Down Expand Up @@ -58,23 +78,6 @@ extension UIImageView{
}
}

func AddGifImage(gifImage:UIImage){
AddGifImage(gifImage,memoryLimit: 20)
}

func AddGifImage(gifImage:UIImage,memoryLimit:Int){
self.gifImage = gifImage
self.displayOrderIndex = 0
self.currentImage = UIImage(CGImage: CGImageSourceCreateImageAtIndex(self.gifImage.imageSource!,0,nil)!)
if(self.gifImage.imageSize>=memoryLimit){
self.timer = CADisplayLink(target: self, selector: Selector("updateFrameWithoutCache"))
}else{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0),prepareCache)
self.timer = CADisplayLink(target: self, selector: Selector("updateFrameWithCache"))
}
timer!.frameInterval = gifImage.displayRefreshFactor!
timer!.addToRunLoop(.mainRunLoop(), forMode: NSRunLoopCommonModes)
}
func prepareCache(){
for i in 0..<self.gifImage.displayOrder!.count {
let image = UIImage(CGImage: CGImageSourceCreateImageAtIndex(self.gifImage.imageSource!,self.gifImage.displayOrder![i],nil)!)
Expand Down

0 comments on commit 951bb33

Please sign in to comment.