- 浏览: 318179 次
- 性别:
- 来自: 杭州
最新评论
-
atgoingguoat:
R.drawable.icon是LOG图
android九宫格实现 -
atgoingguoat:
android:src="@drawable/ico ...
android九宫格实现 -
修博龙泉:
旋转view:
CGAffineTransform at ...
动画-图片旋转 -
修博龙泉:
阻尼效果图片:
CALayer *layer = self.i ...
动画-图片旋转 -
bei-jin-520:
color]sdfsdfsdf
android九宫格实现
#import "SCGIFImageView.h" NSString* filePath = [[NSBundle mainBundle] pathForResource:@"1.gif" ofType:nil]; SCGIFImageView* gifImageView = [[[SCGIFImageView alloc] initWithGIFFile:filePath] autorelease]; gifImageView.frame = CGRectMake(0, 0, gifImageView.image.size.width, gifImageView.image.size.height); gifImageView.center = self.view.center; [self.view addSubview:gifImageView];
SCGIFImageView.h
// // SCGIFImageView.h // TestGIF // // Created by shichangone on 11-7-12. // Copyright 2011 __MyCompanyName__. All rights reserved. // #import <UIKit/UIKit.h> @interface AnimatedGifFrame : NSObject { NSData *data; NSData *header; double delay; int disposalMethod; CGRect area; } @property (nonatomic, copy) NSData *header; @property (nonatomic, copy) NSData *data; @property (nonatomic) double delay; @property (nonatomic) int disposalMethod; @property (nonatomic) CGRect area; @end @interface SCGIFImageView : UIImageView { NSData *GIF_pointer; NSMutableData *GIF_buffer; NSMutableData *GIF_screen; NSMutableData *GIF_global; NSMutableArray *GIF_frames; int GIF_sorted; int GIF_colorS; int GIF_colorC; int GIF_colorF; int animatedGifDelay; int dataPointer; } @property (nonatomic, retain) NSMutableArray *GIF_frames; - (id)initWithGIFFile:(NSString*)gifFilePath; - (id)initWithGIFData:(NSData*)gifImageData; - (void)loadImageData; + (NSMutableArray*)getGifFrames:(NSData*)gifImageData; + (BOOL)isGifImage:(NSData*)imageData; - (void) decodeGIF:(NSData *)GIFData; - (void) GIFReadExtensions; - (void) GIFReadDescriptor; - (bool) GIFGetBytes:(int)length; - (bool) GIFSkipBytes: (int) length; - (NSData*) getFrameAsDataAtIndex:(int)index; - (UIImage*) getFrameAsImageAtIndex:(int)index; @end
SCGIFImageView.m
// // SCGIFImageView.m // TestGIF // // Created by shichangone on 11-7-12. // Copyright 2011 __MyCompanyName__. All rights reserved. // #import "SCGIFImageView.h" @implementation AnimatedGifFrame @synthesize data, delay, disposalMethod, area, header; - (void) dealloc { [data release]; [header release]; [super dealloc]; } @end @implementation SCGIFImageView @synthesize GIF_frames; + (BOOL)isGifImage:(NSData*)imageData { const char* buf = (const char*)[imageData bytes]; if (buf[0] == 0x47 && buf[1] == 0x49 && buf[2] == 0x46 && buf[3] == 0x38) { return YES; } return NO; } + (NSMutableArray*)getGifFrames:(NSData*)gifImageData { SCGIFImageView* gifImageView = [[SCGIFImageView alloc] initWithGIFData:gifImageData]; if (!gifImageView) { return nil; } NSMutableArray* gifFrames = gifImageView.GIF_frames; [[gifFrames retain] autorelease]; [gifImageView release]; return gifFrames; } - (id)initWithGIFFile:(NSString*)gifFilePath { NSData* imageData = [NSData dataWithContentsOfFile:gifFilePath]; return [self initWithGIFData:imageData]; } - (id)initWithGIFData:(NSData*)gifImageData { if (gifImageData.length < 4) { return nil; } if (![SCGIFImageView isGifImage:gifImageData]) { UIImage* image = [UIImage imageWithData:gifImageData]; return [super initWithImage:image]; } [self decodeGIF:gifImageData]; if (GIF_frames.count <= 0) { UIImage* image = [UIImage imageWithData:gifImageData]; return [super initWithImage:image]; } self = [super init]; if (self) { [self loadImageData]; } return self; } - (void)setGIF_frames:(NSMutableArray *)gifFrames { [gifFrames retain]; if (GIF_frames) { [GIF_frames release]; } GIF_frames = gifFrames; [self loadImageData]; } - (void)loadImageData { // Add all subframes to the animation NSMutableArray *array = [[NSMutableArray alloc] init]; for (NSUInteger i = 0; i < [GIF_frames count]; i++) { [array addObject: [self getFrameAsImageAtIndex:i]]; } NSMutableArray *overlayArray = [[NSMutableArray alloc] init]; UIImage *firstImage = [array objectAtIndex:0]; CGSize size = firstImage.size; CGRect rect = CGRectZero; rect.size = size; UIGraphicsBeginImageContext(size); CGContextRef ctx = UIGraphicsGetCurrentContext(); int i = 0; AnimatedGifFrame *lastFrame = nil; for (UIImage *image in array) { // Get Frame AnimatedGifFrame *frame = [GIF_frames objectAtIndex:i]; // Initialize Flag UIImage *previousCanvas = nil; // Save Context CGContextSaveGState(ctx); // Change CTM CGContextScaleCTM(ctx, 1.0, -1.0); CGContextTranslateCTM(ctx, 0.0, -size.height); // Check if lastFrame exists CGRect clipRect; // Disposal Method (Operations before draw frame) switch (frame.disposalMethod) { case 1: // Do not dispose (draw over context) // Create Rect (y inverted) to clipping clipRect = CGRectMake(frame.area.origin.x, size.height - frame.area.size.height - frame.area.origin.y, frame.area.size.width, frame.area.size.height); // Clip Context CGContextClipToRect(ctx, clipRect); break; case 2: // Restore to background the rect when the actual frame will go to be drawed // Create Rect (y inverted) to clipping clipRect = CGRectMake(frame.area.origin.x, size.height - frame.area.size.height - frame.area.origin.y, frame.area.size.width, frame.area.size.height); // Clip Context CGContextClipToRect(ctx, clipRect); break; case 3: // Restore to Previous // Get Canvas previousCanvas = UIGraphicsGetImageFromCurrentImageContext(); // Create Rect (y inverted) to clipping clipRect = CGRectMake(frame.area.origin.x, size.height - frame.area.size.height - frame.area.origin.y, frame.area.size.width, frame.area.size.height); // Clip Context CGContextClipToRect(ctx, clipRect); break; } // Draw Actual Frame CGContextDrawImage(ctx, rect, image.CGImage); // Restore State CGContextRestoreGState(ctx); //delay must larger than 0, the minimum delay in firefox is 10. if (frame.delay <= 0) { frame.delay = 10; } [overlayArray addObject:UIGraphicsGetImageFromCurrentImageContext()]; // Set Last Frame lastFrame = frame; // Disposal Method (Operations afte draw frame) switch (frame.disposalMethod) { case 2: // Restore to background color the zone of the actual frame // Save Context CGContextSaveGState(ctx); // Change CTM CGContextScaleCTM(ctx, 1.0, -1.0); CGContextTranslateCTM(ctx, 0.0, -size.height); // Clear Context CGContextClearRect(ctx, clipRect); // Restore Context CGContextRestoreGState(ctx); break; case 3: // Restore to Previous Canvas // Save Context CGContextSaveGState(ctx); // Change CTM CGContextScaleCTM(ctx, 1.0, -1.0); CGContextTranslateCTM(ctx, 0.0, -size.height); // Clear Context CGContextClearRect(ctx, lastFrame.area); // Draw previous frame CGContextDrawImage(ctx, rect, previousCanvas.CGImage); // Restore State CGContextRestoreGState(ctx); break; } // Increment counter i++; } UIGraphicsEndImageContext(); [self setImage:[overlayArray objectAtIndex:0]]; [self setAnimationImages:overlayArray]; [overlayArray release]; [array release]; // Count up the total delay, since Cocoa doesn't do per frame delays. double total = 0; for (AnimatedGifFrame *frame in GIF_frames) { total += frame.delay; } // GIFs store the delays as 1/100th of a second, // UIImageViews want it in seconds. [self setAnimationDuration:total/100]; // Repeat infinite [self setAnimationRepeatCount:0]; [self startAnimating]; } - (void)dealloc { if (GIF_buffer != nil) { [GIF_buffer release]; } if (GIF_screen != nil) { [GIF_screen release]; } if (GIF_global != nil) { [GIF_global release]; } [GIF_frames release]; [super dealloc]; } - (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]; } [GIF_frames release]; GIF_buffer = [[NSMutableData alloc] init]; GIF_global = [[NSMutableData alloc] init]; GIF_screen = [[NSMutableData alloc] init]; GIF_frames = [[NSMutableArray alloc] init]; // Reset file counters to 0 dataPointer = 0; [self GIFSkipBytes: 6]; // GIF89a, throw away [self GIFGetBytes: 7]; // Logical Screen Descriptor // Deep copy [GIF_screen setData: GIF_buffer]; // Copy the read bytes into a local buffer on the stack // For easy byte access in the following lines. 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)]; // Deep copy [GIF_global setData:GIF_buffer]; } unsigned char bBuffer[1]; while ([self GIFGetBytes:1] == YES) { [GIF_buffer getBytes:bBuffer length:1]; if (bBuffer[0] == 0x3B) { // This is the end break; } switch (bBuffer[0]) { case 0x21: // Graphic Control Extension (#n of n) [self GIFReadExtensions]; break; case 0x2C: // Image Descriptor (#n of n) [self GIFReadDescriptor]; break; } } // clean up stuff [GIF_buffer release]; GIF_buffer = nil; [GIF_screen release]; GIF_screen = nil; [GIF_global release]; GIF_global = nil; } - (void) GIFReadExtensions { // 21! But we still could have an Application Extension, // so we want to check for the full signature. unsigned char cur[1], prev[1]; [self GIFGetBytes:1]; [GIF_buffer getBytes:cur length:1]; while (cur[0] != 0x00) { // TODO: Known bug, the sequence F9 04 could occur in the Application Extension, we // should check whether this combo follows directly after the 21. if (cur[0] == 0x04 && prev[0] == 0xF9) { [self GIFGetBytes:5]; AnimatedGifFrame *frame = [[AnimatedGifFrame alloc] init]; unsigned char buffer[5]; [GIF_buffer getBytes:buffer length:5]; frame.disposalMethod = (buffer[0] & 0x1c) >> 2; //NSLog(@"flags=%x, dm=%x", (int)(buffer[0]), frame.disposalMethod); // We save the delays for easy access. frame.delay = (buffer[1] | buffer[2] << 8); 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]; } frame.header = [NSData dataWithBytes:board length:8]; [GIF_frames addObject:frame]; [frame release]; break; } prev[0] = cur[0]; [self GIFGetBytes:1]; [GIF_buffer getBytes:cur length:1]; } } - (void) GIFReadDescriptor { [self GIFGetBytes:9]; // Deep copy NSMutableData *GIF_screenTmp = [NSMutableData dataWithData:GIF_buffer]; unsigned char aBuffer[9]; [GIF_buffer getBytes:aBuffer length:9]; CGRect rect; rect.origin.x = ((int)aBuffer[1] << 8) | aBuffer[0]; rect.origin.y = ((int)aBuffer[3] << 8) | aBuffer[2]; rect.size.width = ((int)aBuffer[5] << 8) | aBuffer[4]; rect.size.height = ((int)aBuffer[7] << 8) | aBuffer[6]; AnimatedGifFrame *frame = [GIF_frames lastObject]; frame.area = rect; 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]; } // Add Graphic Control Extension Frame (for transparancy) [GIF_string appendData:frame.header]; 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)]; // save the frame into the array of frames frame.data = GIF_string; } - (bool) GIFGetBytes:(int)length { if (GIF_buffer != nil) { [GIF_buffer release]; // Release old buffer GIF_buffer = nil; } if ((NSInteger)[GIF_pointer length] >= dataPointer + length) // Don't read across the edge of the file.. { GIF_buffer = [[GIF_pointer subdataWithRange:NSMakeRange(dataPointer, length)] retain]; dataPointer += length; return YES; } else { return NO; } } - (bool) GIFSkipBytes: (int) length { if ((NSInteger)[GIF_pointer length] >= dataPointer + length) { dataPointer += length; return YES; } else { return NO; } } - (NSData*) getFrameAsDataAtIndex:(int)index { if (index < (NSInteger)[GIF_frames count]) { return ((AnimatedGifFrame *)[GIF_frames objectAtIndex:index]).data; } else { return nil; } } - (UIImage*) getFrameAsImageAtIndex:(int)index { NSData *frameData = [self getFrameAsDataAtIndex: index]; UIImage *image = nil; if (frameData != nil) { image = [UIImage imageWithData:frameData]; } return image; } @end
发表评论
-
CCMenu 与 CCMenuItem
2013-11-09 11:52 870引入#import "ccDeprecate ... -
抛物线的精灵
2013-11-08 15:04 825// 抛物线 //mSprite:需要做抛物线的精灵 ... -
卡马克卷轴算法
2013-11-05 15:35 2127念 这里使用简化的概念,精确的定义请参考计算机图形学中二维观察 ... -
git 大招
2013-11-04 19:54 1582Last login: Mon Nov 4 19:30:1 ... -
AVAudioRecorder MAV格式录音
2013-08-15 21:13 1215//录音设置 NSDictionary * ... -
uilable根据字符串长度变化
2013-08-01 15:18 917CGSize labelSize = [ ... -
ios 文本自动换行
2013-07-30 19:52 1062// //自动换行 // UILabel *l ... -
ios 文本框随着键盘高度变化而变化
2013-07-29 18:22 2273监听键盘高度变化 [[NSNotificationC ... -
IOS开发苹果官方Sample Code及下载地址
2013-07-11 11:17 1619在线浏览地址:https://developer.apple ... -
苹果推送通知服务(APNs)编程(转)
2013-06-07 11:19 1315iPhone 对于应用程序在后台运行有诸多限制(除非你越狱) ... -
cell 数据重复
2013-06-03 15:21 1046static NSString *CellIdentifi ... -
ios NSDate NSTring long 时间戳与字符串转换
2013-05-22 11:09 27018一,转化的方法为 NSString *timeS ... -
关于缺少各种framework出现的错误累结(转)
2013-05-16 16:47 1416博客分类: iosiPhone开发 iosiPhone开发 ... -
动画-图片旋转
2013-05-13 11:28 1466旋转: iv = [[UIImageView alloc] ... -
UINavicationController
2013-05-13 09:41 909如果楼主想要使用UINavigationController中 ... -
NSTimer-动态修改Interval的值
2013-05-06 09:38 931NSTimer使用例子: NSTimer *sh ... -
UIScrollView的属性总结
2013-04-27 10:00 948UIScrollView的属性总结 属性 作用 CGPoint ... -
单例设置
2013-04-27 09:51 835+ (RootScrollView *)shareIn ... -
颜色设置
2013-04-27 09:50 722[Globle colorFromHexRGB:@&quo ... -
翻转动画
2013-04-11 16:11 817CGContextRef context ...
相关推荐
在iOS开发中,GIF动画的使用已经成为一种常见的需求,特别是在社交、娱乐或者信息展示类应用中。GIF格式因其小巧且支持循环播放的特点,深受开发者喜爱。本篇将详细介绍如何在iOS应用中实现GIF动画的显示。 一、GIF...
这些库能够解析并播放GIF文件,提供更便捷的方法在UIImageView上显示GIF动画。 4. **`SDWebImage`库的使用**: `SDWebImage`是一个流行的图片加载库,它不仅支持网络图片的异步加载,还支持GIF显示。要使用`...
在iOS开发中,UIImages是展示静态图像的基本类,但有时候我们需要展示动态效果,比如GIF动画。本教程将深入探讨如何从GIF动画中创建一个动态的UIImages对象,适用于iOS应用源码实践。 首先,我们要理解GIF格式的...
在iOS平台上,展示GIF图片是一项常见的需求,特别是在创建动态表情、加载指示或者动画效果时。在Xcode 6.2及更高版本中,由于原生SDK并不直接支持GIF格式,开发者通常需要借助第三方库或者自定义解决方案来实现。本...
为了实现在UIImageView上展示GIF动画,开发者通常会借助第三方库,比如本例中提到的`SDWebImage`。`SDWebImage`是一个非常流行且功能强大的图片加载库,它不仅支持从网络加载图片,还提供了缓存机制和处理各种图片...
总之,通过使用`FLAnimatedImage`库,开发者可以在iOS应用的启动过程中展示GIF动画,提高用户体验。正确集成和管理这个库,以及适时地启动和停止动画,是实现这一功能的关键。同时,结合其他界面元素,如进度条,...
在iOS开发中,为了使应用更...通过以上方法,你就可以在iOS应用中完美展示GIF动画了。在实际开发中,还要根据项目需求和性能要求选择最适合的解决方案。同时,不断学习和掌握新的技术和工具,才能不断提升iOS开发技能。
在iOS开发中,显示GIF图片是一个常见的需求,特别是在创建社交、娱乐或者信息展示类应用时。GIF是一种流行的动画格式,它支持循环播放和透明度,为用户提供了一种生动的视觉体验。本文将深入探讨如何在iOS应用中实现...
本教程将详细介绍如何在iOS应用中使用UIImageView来展示GIF动画,同时结合SDWebImage和SCGifExample这两个开源库进行实践。 首先,`UIImageView`是苹果提供的一种用于展示静态图片的视图控件。默认情况下,它不支持...
在iOS开发中,加载动图(GIF)是常见的需求,特别是在等待数据加载或展示交互效果时。OC(Objective-C)作为苹果平台的主要编程语言之一,虽然原生并不支持GIF,但通过第三方库可以方便地实现GIF的显示。在本话题中...
在移动应用和网页开发中,GIF...开发者需要根据项目需求和目标平台,选择最佳方案,并进行细致的优化,以实现流畅、高效的GIF动画展示。通过不断学习和实践,你可以更好地掌握这一技能,为用户提供更优质的互动体验。
在iOS开发中,实现Gif动画的播放是一个常见的需求,特别是在多媒体应用中。Gif是一种支持多帧图像的格式,可以用来创建简单的动画效果。在本教程中,我们将重点讨论如何使用Swift语言来处理和播放Gif动画。我们将...
在标题中提到的“swift-iOS的完整动画GIF支持”很可能是指一个开源库或者方法,它提供了全面的功能来解析和播放GIF动画。 1. **函数**:在实现GIF动画时,我们通常会用到一系列的函数来读取、解析和绘制GIF的每一帧...
总之,这个“iOS gif 原帧真实播放类库(有Demo)”提供了对GIF动画的高效处理,尤其强调了原帧的真实播放,这对于需要高质量GIF体验的应用来说非常关键。通过分析Demo,开发者可以获得关于如何在自己的应用中实现...
在这个例子中,我们关注的是如何在UIImageView中展示GIF动画。首先,我们需要导入SDWebImage的相关头文件,包括: 1. UIButton+WebCache.h:扩展UIButton,使其具有加载网络图片的能力。 2. SDWebImageManager.h:...
这为跨平台开发提供了便利,无论是在Windows、Linux还是Mac OS,或者是Android、iOS等移动系统,都能实现一致的GIF动画展示效果。 控件的核心特性可能包括: 1. **高效解码**:优化的算法使得GIF文件能快速高效...
主要文件有两个:一个名为"折叠.gif"的动画图像,很可能是展示折叠效果的示例;另一个是"a.txt",可能是一份简短的文字说明或代码片段。 首先,让我们深入了解一下iOS中的视图动画。苹果的UIKit框架提供了强大的...
"20个进度条GIF动画"这个资源包包含的是20种不同的动态进度条图形,这些GIF格式的文件适用于多种场景,如网页设计、软件开发、移动应用或是任何需要显示进度的地方。 首先,我们要理解进度条的基本概念。进度条通常...
在iOS开发中,有时我们需要将GIF动画转换为动态的UIImage对象,以便在我们的应用程序中显示这些动画。这个"IOS应用源码——从GIF动画创建一个动态UIImages 对象.zip"提供了一个实用的解决方案。它包含了一段源代码,...
在iOS开发中,有时我们需要将GIF动画集成到应用程序中,为用户提供更加丰富的交互体验。这个压缩包文件“从GIF动画创建一个动态UIImages 对象”提供了关于如何在iOS应用中实现这一功能的源码示例。接下来,我们将...