How to parse and display GIF in IOS
When chatting, we often use a lot of funny GIF expressions. Sometimes a thousand words are really inferior to a GIF. I used to think about GIF as a common format, which should be supported by all major platforms. I learned that a GIF was to be loaded as a transition animation in the previous two days. I checked the help documentation for half a day, I found thatThere is no ready-made class that supports loading and playing GIF images.
So I simply searched the internet and found two usefulCode. The URLs are as follows:
Three methods to display GIF images
Andrei512 /Gifloader. h
Both methods use the ImageIO library to parse GIF files, and then perform animation display on your own. Now, the idea of displaying GIF animation is clear.
We know that a GIF is composed of a burst of pictures, and the playing of each frame may often be different. Observe the above two examples, they do not often process the display of each frame in the GIF. The result is that each frame in the GIF is played forward at a fixed speed, obviously, this does not always meet the requirements.
Therefore, I wrote a GIF Parsing tool class to solve the problem of playing each frame and following the display time corresponding to each frame.
ProgramThe idea is as follows:
1. First, use cgimagesource in the ImageIO library in the GIF file.
2. Get the total number of frames in the GIF file and the display time of each frame through cgimagesource.
3. Use cakeyframeanimation to play the GIF animation.
The following is the code for parsing and playing GIF tools:
Svgifview
// // Svgifview. h // Svgifsample // // Created by MAPLE on 3/28/13. // Copyright (c) 2013 smileevday. All rights reserved. // // QQ: 1592232964 # Import <Uikit/uikit. h> @ Interface Svgifview: uiview /* * @ Brief desingated initializer */ -( ID ) Initwithcenter :( cgpoint) center fileurl :( nsurl * ) Fileurl; /* * @ Brief start GIF Animation */ -(Void ) Startgif; /* * @ Brief stop GIF Animation */ -( Void ) Stopgif; /* * @ Brief get frames image (cgimageref) in GIF */ + (Nsarray *) framesingif :( nsurl * ) Fileurl; @ End
Svgifview. m
// // Svgifview. m // Svgifsample // // Created by MAPLE on 3/28/13. // Copyright (c) 2013 smileevday. All rights reserved. // // QQ: 1592232964 # Import " Svgifview. h " # Import <ImageIO/ImageIO. h> # Import <Quartzcore/coreanimation. h> /* * @ Brief resolving GIF Information */ Void Getframeinfo (cfurlref URL, nsmutablearray * frames, nsmutablearray * delaytimes, cgfloat * totaltime, cgfloat * gifwidth, cgfloat * Gifheight) {cgimagesourceref gifsource = Cgimagesourcecreatewithurl (URL, null ); // Get Frame Count Size_t framecount = Cgimagesourcegetcount (gifsource ); For (Size_t I = 0 ; I <framecount; ++ I ){ // Get each frame Cgimageref frame = Cgimagesourcecreateimageatindex (gifsource, I, null); [frames addobject :( ID ) Frame]; cgimagerelease (FRAME ); // Get GIF info with each frame Nsdictionary * dict = (nsdictionary * ) Cgimagesourcecopypropertiesatindex (gifsource, I, null); nslog ( @" Kcgimagepropertygifdictionary % @ " , [Dict valueforkey :( nsstring * ) Kcgimagepropertygifdictionary]); // Get GIF size If (Gifwidth! = NULL & gifheight! = Null ){ * Gifwidth = [[dict valueforkey :( nsstring * ) Kcgimagepropertypixelwidth] floatvalue]; * Gifheight = [[dict valueforkey :( nsstring * ) Kcgimagepropertypixelheight] floatvalue];} // In kcgimagepropertygifdictionary, the values of kcgimagepropertygifdelaytime and kcgimagepropertygifunclampeddelaytime are the same. Nsdictionary * gifdict = [dict valueforkey :( nsstring * ) Kcgimagepropertygifdictionary]; [delaytimes addobject: [gifdict valueforkey :( nsstring * ) Kcgimagepropertygifdelaytime]; If (Totaltime ){ * Totaltime = * totaltime + [[gifdict valueforkey :( nsstring * ) Kcgimagepropertygifdelaytime] floatvalue] ;}} @ Interface Svgifview () {nsmutablearray * _ Frames; nsmutablearray * _ Framedelaytimes; cgfloat _ totaltime; // Seconds Cgfloat _ width; cgfloat _ height ;} @ End @ Implementation Svgifview -( ID ) Initwithcenter :( cgpoint) center fileurl :( nsurl * ) Fileurl; {self = [Super initwithframe: cgrectzero]; If (Self) {_ Frames = [[Nsmutablearray alloc] init]; _ framedelaytimes = [[Nsmutablearray alloc] init]; _ width = 0 ; _ Height = 0 ; If (Fileurl) {getframeinfo (cfurlref) fileurl, _ frames, _ framedelaytimes, & _ Totaltime, & _ width ,& _ Height);} self. Frame = Cgrectmake (0 , 0 , _ Width, _ height); self. Center = Center ;} Return Self ;} + (Nsarray *) framesingif :( nsurl * ) Fileurl {nsmutablearray * Frames = [nsmutablearray arraywithcapacity: 3 ]; Nsmutablearray * Delays = [nsmutablearray arraywithcapacity: 3 ]; Getframeinfo (cfurlref) fileurl, frames, delays, null ); Return Frames ;} -( Void ) Startgif {cakeyframeanimation * Animation = [cakeyframeanimation animationwithkeypath: @" Contents " ]; Nsmutablearray * Times = [nsmutablearray arraywithcapacity: 3 ]; Cgfloat currenttime = 0 ; Int Count =_ Framedelaytimes. count; For ( Int I = 0 ; I <count; ++ I) {[times addobject: [nsnumber numberwithfloat :( currenttime / _ Totaltime)]; currenttime + = [[_ Framedelaytimes objectatindex: I] floatvalue];} [animation setkeytimes: Times]; nsmutablearray * Images = [nsmutablearray arraywithcapacity: 3 ]; For ( Int I = 0 ; I <count; ++ I) {[images addobject: [_ frames objectatindex: I];} [animation setvalues: images]; [animation settimingfunction: [camediatimingfunction functionwithname: Duration]; animation. Duration = _ Totaltime; animation. Delegate = Self; animation. repeatcount = 5 ; [Self. layer addanimation: animation forkey: @" Gifanimation " ];} -( Void ) Stopgif {[self. layer removeallanimations];} // Remove contents when animation end -( Void ) Animationdidstop :( caanimation * ) Anim finished :( bool) Flag {self. layer. Contents = Nil ;} // Only override drawrect: If you perform custom drawing. // An empty implementation adversely affects performance during animation. -( Void ) Drawrect :( cgrect) rect { // Drawing code } @ End
The code is very short and easy to explain. The C function at the beginning is mainly used to parse GIF. The C function is used because I want to return multiple messages, while objective-C can only return one parameter, moreover, objective-C and C can be easily mixed for programming.
Testing GitHub address: https://github.com/smileEvday/SvGifView/