你的分享就是我们的动力 ---﹥

将gif转换成animated gif

时间:2012-07-16 16:17来源:www.chengxuyuans.com 点击:

AnimatedGif.h

?

#ifdef TARGET_OS_IPHONE			
#import <UIKit/UIKit.h>
#else
#import <Cocoa/Cocoa.h>
#endif TARGET_OS_IPHONE	

@interface AnimatedGifQueueObject : NSObject {
    UIImageView *uiv;
    NSURL *url;
}

@property (nonatomic, retain) UIImageView *uiv;
@property (nonatomic, retain) NSURL *url;

@end

@interface AnimatedGif : NSObject {
	NSData *GIF_pointer;
	NSMutableData *GIF_buffer;
	NSMutableData *GIF_screen;
	NSMutableData *GIF_global;
	NSMutableData *GIF_frameHeader;
	
	NSMutableArray *GIF_delays;
	NSMutableArray *GIF_framesData;
    
    NSMutableArray *imageQueue;
	bool busyDecoding;
	
	int GIF_sorted;
	int GIF_colorS;
	int GIF_colorC;
	int GIF_colorF;
	int animatedGifDelay;
	
	int dataPointer;
    
    UIImageView *imageView;
}

@property (nonatomic, retain) UIImageView *imageView;
@property bool busyDecoding;

- (void) addToQueue: (AnimatedGifQueueObject *) agqo;
+ (UIImageView *) getAnimationForGifAtUrl: (NSURL *) animationUrl;
- (void) decodeGIF:(NSData *)GIF_Data;
- (void) GIFReadExtensions;
- (void) GIFReadDescriptor;
- (bool) GIFGetBytes:(int)length;
- (bool) GIFSkipBytes: (int) length;
- (NSMutableData *) getFrameAsDataAtIndex:(int)index;
- (UIImage *) getFrameAsImageAtIndex:(int)index;
- (UIImageView *) getAnimation;

@end

?

AnimatedGif.m

?

#import "AnimatedGif.h"

@implementation AnimatedGifQueueObject

@synthesize uiv;
@synthesize url;

@end

@implementation AnimatedGif

static AnimatedGif *instance;

@synthesize imageView;
@synthesize busyDecoding;

+ (AnimatedGif *) sharedInstance {
    if (instance == nil) {
        instance = [[AnimatedGif alloc] init];
    }
    
    return instance;
}

+ (UIImageView *) getAnimationForGifAtUrl:(NSURL *)animationUrl {   
    AnimatedGifQueueObject *agqo = [[AnimatedGifQueueObject alloc] init];
    [agqo setUiv: [[UIImageView alloc] init]];
    [[agqo uiv] autorelease]; 
    [agqo setUrl: animationUrl]; 
    [[AnimatedGif sharedInstance] addToQueue: agqo];
    [agqo release];
    
    if ([[AnimatedGif sharedInstance] busyDecoding] != YES) {
        [[AnimatedGif sharedInstance] setBusyDecoding: YES];
        [[AnimatedGif sharedInstance] performSelector:@selector(asynchronousLoading) withObject:nil afterDelay:0.0];
    }
    
    return [agqo uiv];
}

- (void) asynchronousLoading {
	while ([imageQueue count] > 0) {
    	NSData *data = [NSData dataWithContentsOfURL: [(AnimatedGifQueueObject *) [imageQueue objectAtIndex: 0] url]];
        imageView = [[imageQueue objectAtIndex: 0] uiv];
    	[self decodeGIF: data];
   	 	UIImageView *tempImageView = [self getAnimation];
   	 	[imageView setImage: [tempImageView image]];
    	[imageView sizeToFit];
    	[imageView setAnimationImages: [tempImageView animationImages]];
    	[imageView startAnimating];
        [imageQueue removeObjectAtIndex:0];
    }
    busyDecoding = NO;
}

- (void) addToQueue: (AnimatedGifQueueObject *) agqo {
    [imageQueue addObject: agqo];
}

- (id) init {
    if (self = [super init])
    {
        imageQueue = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)decodeGIF:(NSData *)GIFData {
	GIF_pointer = GIFData;
    
    if (GIF_buffer != nil) {
        [GIF_buffer release];
    }
    
    if (GIF_global != nil) {
        [GIF_global release];
    }
    
    if (GIF_screen != nil) {
        [GIF_screen release];
    }
    
	if (GIF_delays != nil) {
        [GIF_delays release];
    }
    
    if (GIF_framesData != nil) {
        [GIF_framesData release];
    }
    
    GIF_buffer = [[NSMutableData alloc] init];
	GIF_global = [[NSMutableData alloc] init];
	GIF_screen = [[NSMutableData alloc] init];
	GIF_frameHeader = nil;
    
	GIF_delays = [[NSMutableArray alloc] init];
	GIF_framesData = [[NSMutableArray alloc] init];
    
	dataPointer = 0;
	
	[self GIFSkipBytes: 6]; 
	[self GIFGetBytes: 7]; 
	
	[GIF_screen setData: GIF_buffer];
	
    int length = [GIF_buffer length];
	unsigned char aBuffer[length];
	[GIF_buffer getBytes:aBuffer length:length];
	
	if (aBuffer[4] & 0x80) GIF_colorF = 1; else GIF_colorF = 0; 
	if (aBuffer[4] & 0x08) GIF_sorted = 1; else GIF_sorted = 0;
	GIF_colorC = (aBuffer[4] & 0x07);
	GIF_colorS = 2 << GIF_colorC;
	
	if (GIF_colorF == 1) {
		[self GIFGetBytes: (3 * GIF_colorS)];
		[GIF_global setData:GIF_buffer];
	}
	
	unsigned char bBuffer[1];
	while ([self GIFGetBytes:1] == YES) {
        [GIF_buffer getBytes:bBuffer length:1];
        
        if (bBuffer[0] == 0x3B) { 
            break;
        }
        
        switch (bBuffer[0]) {
            case 0x21:
                [self GIFReadExtensions];
                break;
            case 0x2C:
                [self GIFReadDescriptor];
                break;
        }
	}
	
	[GIF_buffer release];
    GIF_buffer = nil;
    
	[GIF_screen release];
    GIF_screen = nil;
    
	[GIF_global release];	
    GIF_global = nil;
}

- (NSMutableData *) getFrameAsDataAtIndex:(int)index {
	if (index < [GIF_framesData count]) {
		return [GIF_framesData objectAtIndex:index];
	} else {
		return nil;
	}
}

- (UIImage *) getFrameAsImageAtIndex:(int)index {
    NSData *frameData = [self getFrameAsDataAtIndex: index];
    UIImage *image = nil;
    
    if (frameData != nil) {
		image = [UIImage imageWithData:frameData];
    }    
    return image;
}

- (UIImageView *) getAnimation {
	if ([GIF_framesData count] > 0) {
        if (imageView != nil) {
            [imageView setImage:[self getFrameAsImageAtIndex:0]];
            [imageView sizeToFit];
        } else {
            imageView = [[UIImageView alloc] initWithImage:[self getFrameAsImageAtIndex:0]];
        }
        
		NSMutableArray *array = [[NSMutableArray alloc] init];
		for (int i = 0; i < [GIF_framesData count]; i++) {		
			[array addObject: [self getFrameAsImageAtIndex:i]];
		}
		
		[imageView setAnimationImages:array];
        [array release];
        
		double total = 0;
		for (int i = 0; i < [GIF_delays count]; i++) {
			total += [[GIF_delays objectAtIndex:i] doubleValue];
		}
        
		[imageView setAnimationDuration:total / 100];
		[imageView setAnimationRepeatCount:0];
        [imageView startAnimating];
        [imageView autorelease];
        
		return imageView;
	} else {
		return nil;
	}
}

- (void)GIFReadExtensions {
	unsigned char cur[1], prev[1];
    [self GIFGetBytes:1];
    [GIF_buffer getBytes:cur length:1];
    
	while (cur[0] != 0x00) {
		if (cur[0] == 0x04 && prev[0] == 0xF9) {
			[self GIFGetBytes:5];
            
			unsigned char buffer[5];
			[GIF_buffer getBytes:buffer length:5];
            
			[GIF_delays addObject:[NSNumber numberWithInt:(buffer[1] | buffer[2] << 8)]];
            
			if (GIF_frameHeader == nil) {
			    unsigned char board[8];
				board[0] = 0x21;
				board[1] = 0xF9;
				board[2] = 0x04;
				
				for(int i = 3, a = 0; a < 5; i++, a++) {
					board[i] = buffer[a];
				}
                
				GIF_frameHeader = [NSMutableData dataWithBytes:board length:8];
			}            
			break;
		}		
		prev[0] = cur[0];
        [self GIFGetBytes:1];
		[GIF_buffer getBytes:cur length:1];
	}	
}

- (void) GIFReadDescriptor {	
	[self GIFGetBytes:9];
    
	NSMutableData *GIF_screenTmp = [NSMutableData dataWithData:GIF_buffer];
	
	unsigned char aBuffer[9];
	[GIF_buffer getBytes:aBuffer length:9];
	
	if (aBuffer[8] & 0x80) GIF_colorF = 1; else GIF_colorF = 0;
	
	unsigned char GIF_code = GIF_colorC, GIF_sort = GIF_sorted;
	
	if (GIF_colorF == 1) {
		GIF_code = (aBuffer[8] & 0x07);
        
		if (aBuffer[8] & 0x20) {
            GIF_sort = 1;
        } else {
        	GIF_sort = 0;
        }
	}
	
	int GIF_size = (2 << GIF_code);
	
	size_t blength = [GIF_screen length];
	unsigned char bBuffer[blength];
	[GIF_screen getBytes:bBuffer length:blength];
	
	bBuffer[4] = (bBuffer[4] & 0x70);
	bBuffer[4] = (bBuffer[4] | 0x80);
	bBuffer[4] = (bBuffer[4] | GIF_code);
	
	if (GIF_sort) {
		bBuffer[4] |= 0x08;
	}
	
    NSMutableData *GIF_string = [NSMutableData dataWithData:[[NSString stringWithString:@"GIF89a"] dataUsingEncoding: NSUTF8StringEncoding]];
	[GIF_screen setData:[NSData dataWithBytes:bBuffer length:blength]];
    [GIF_string appendData: GIF_screen];	
	
	if (GIF_colorF == 1) {
		[self GIFGetBytes:(3 * GIF_size)];
        [GIF_string appendData: GIF_buffer];
	} else {
		[GIF_string appendData: GIF_global];
	}
    
	[GIF_string appendData:GIF_frameHeader];
	
	char endC = 0x2c;
	[GIF_string appendBytes:&endC length:sizeof(endC)];
	
	size_t clength = [GIF_screenTmp length];
	unsigned char cBuffer[clength];
	[GIF_screenTmp getBytes:cBuffer length:clength];
	
	cBuffer[8] &= 0x40;
	
	[GIF_screenTmp setData:[NSData dataWithBytes:cBuffer length:clength]];
	
	[GIF_string appendData: GIF_screenTmp];
	[self GIFGetBytes:1];
	[GIF_string appendData: GIF_buffer];
	
	while (true) {
		[self GIFGetBytes:1];
		[GIF_string appendData: GIF_buffer];
		
		unsigned char dBuffer[1];
		[GIF_buffer getBytes:dBuffer length:1];
		
		long u = (long) dBuffer[0];
        
		if (u != 0x00) {
			[self GIFGetBytes:u];
			[GIF_string appendData: GIF_buffer];
        } else {
            break;
        }
	}
	
	endC = 0x3b;
	[GIF_string appendBytes:&endC length:sizeof(endC)];
    
	[GIF_framesData addObject:[GIF_string copy]];
}

- (bool) GIFGetBytes: (int) length {
    if (GIF_buffer != nil) {
        [GIF_buffer release]; 
        GIF_buffer = nil;
    }
    
	if ([GIF_pointer length] >= dataPointer + length) {
		GIF_buffer = [[GIF_pointer subdataWithRange:NSMakeRange(dataPointer, length)] retain];
        dataPointer += length;
		return YES;
	} else {
        return NO;
	}
}

- (bool) GIFSkipBytes: (int) length {
    if ([GIF_pointer length] >= dataPointer + length) {
        dataPointer += length;
        return YES;
    } else {
    	return NO;
    }
}

- (void) dealloc {
    if (GIF_buffer != nil) {
	    [GIF_buffer release];
    }
    
    if (GIF_screen != nil) {
		[GIF_screen release];
    }
    
    if (GIF_global != nil) {
        [GIF_global release];
    }
    
    if (GIF_delays != nil) {
		[GIF_delays release];
    }
    
    if (GIF_framesData != nil) {
		[GIF_framesData release];
    }
    
	[super dealloc];
}

@end

?

示例:

?

NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"logo" ofType:@"gif"]];
UIImageView *animationGif = [AnimatedGif getAnimationForGifAtUrl: url];
[animatedGifImageView addSubview:animationGif];

本文地址http://www.chengxuyuans.com/iPhone_IOS/41987.html