CGImageSource的用法

导入 ImageIO.framework
#import 
<ImageIO/ImageIO.h> 

1.创建CGImageSourceRef
1
2
NSString * imagePath = [ [ NSBundle bundleForClass : self . class ] pathForImageResource : @ "test.png" ] ;
CGImageSourceRef imageSource = CGImageSourceCreateWithURL ( ( __bridge CFURLRef ) [ NSURL fileURLWithPath : imagePath ] , NULL ) ;
2.获取图像
CGImageRef imageRef = CGImageSourceCreateImageAtIndex ( imageSource , 0 , NULL ) ;
3.创建图像的缩略图

//缩略图的宽和高
 
double thumbnailWidth = xxx , thumbnailHeight = xxx ;
 
//缩略图的信息的字典
 
NSDictionary * thumbnailInfo = @ {
 
( NSString * ) kCGImageSourceCreateThumbnailFromImageAlways : @ YES ,
 
( NSString * ) kCGImageSourceThumbnailMaxPixelSize : [ NSNumber numberWithInt : MAX ( thumbnailWidth , thumbnailHeight ) ] ,
 
( NSString * ) kCGImageSourceCreateThumbnailWithTransform : @ YES ,
 
} ;
 
//得到缩略图
 
CGImageRef imageRef = CGImageSourceCreateThumbnailAtIndex ( imageSource , 0 , ( __bridge C FDictionaryRef ) thumbnailInfo ) ;

4.获取图像的属性信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CFDictionaryRef imageInfo = CGImageSourceCopyPropertiesAtIndex ( imageSource , 0 , NULL ) ;
 
//像素的宽
 
NSNumber * pixelWidthObj = ( __bridge NSNumber * ) CFDictionaryGetValue ( imageInfo , kCGImagePropertyPixelWidth ) ;
 
//像素的高
 
NSNumber * pixelHeightObj = ( __bridge NSNumber * ) CFDictionaryGetValue ( imageInfo , kCGImagePropertyPixelHeight ) ;
 
//图像的旋转方向
 
NSInteger orientation = [ ( __bridge NSNumber * ) CFDictionaryGetValue ( imageInfo , kCGImagePropertyOrientation ) integerValue ] ;
  //时间间隔
NSNumber *number = fromCF CFDictionaryGetValue (gifProperties, kCGImagePropertyGIFUnclampedDelayTime );  
//Exif信息
 
NSDictionary * exifInfo = ( __bridge NSDictionary * ) CFDictionaryGetValue ( imageInfo , kCGImagePropertyExifAuxDictionary ) ;
   

5.GIF图片动画
原理:GIF图片包含了图片张数,以及每张图片的信息,如延迟时间(ms),因此只要获取到每张gif子图,然后动画时间求和,[UIImage animatedImageWithImages:xx duration:xx];
但是这里有一个问题,因为这样gif里的每张图片动画时长会平均到gif动画时间里,实际上,每张图的动画时间是不同的。假设一张GIF有三张图,每张图为分别为:0.2、0.3、0.5;但是如果直接调用,动画时间就变成:0.33、0.33、0.33,并不符合预期;


那解决方式是: 
根据gif格式,,每张图片时间间隔为N*0.01s;N为不为0的正整数,如果未获取到值,默认N为1,在上面的0.2秒,0.3秒,0.5秒钟,N分别为:20、30、50,我们取出他们的最大公约数,为10,这时候,图片分别为20/10、30/10、50/10张,放入数组中,此时有10张图,总动画时间依然为1s,但是每张图的动画分别为都为0.1,但是因为只有三种图,看起来的效果就像0.2s图片1,0.3s图片2,0.5秒图片3,也就达到了我们想要的目的了。



#if __has_feature(objc_arc)

#define toCF (__bridge CFTypeRef)

#define fromCF (__bridge id)

#else

#define toCF (CFTypeRef)

#define fromCF (id)

#endif

伪代码

 size_t const count = CGImageSourceGetCount(source);

 CGImageRef images[count]; 

    for (size_t i = 0; i < count; ++i) {

        imagesOut[i] = CGImageSourceCreateImageAtIndex(source, i, NULL);

        delayCentisecondsOut[i] = 获取间隔秒数,看上面,这里获取的是N;

    } 
int duration= 
delayCentisecondsOut求和;

int frameCount=duration/最小公约数;
 

 NSArray *const frames=重复每个图片的个数,然后累计放到一个数组;
 

 UIImage *const animation = [UIImage animatedImageWithImages:frames duration:(NSTimeInterval)totalDurationCentiseconds / 100.0];


注意:cf create的图片和字典对象,都是需要手动释放的,

附:求最大公约数代码:

static int vectorGCD(size_t const count, int const *const values) {

    int gcd = values[0];

    for (size_t i = 1; i < count; ++i) {

        gcd = pairGCD(values[i], gcd);

    }

    return gcd;

}  

static int pairGCD(int a, int b) {

    if (a < b)

        return pairGCD(b, a);

    while (true) {

        int const r = a % b;

        if (r == 0)

            return b;

        a = b;

        b = r;

    }

}  
 
6.边下载边显示
原理:任何文件都是按照一定格式的,一般文件格式都在文件的header中,imageIO库就是根据先行下载的图片头,构建一个空白图片(其实工作量很多,包括各种图片类型、数据等解码,然后空白图和已有数据编码成一个图片),然后新来的多少数据边覆盖空白部分,直到最后完成。 
 
创建: CGImageSourceRef imageSource =   CGImageSourceCreateIncremental ( NULL );

更新:CGImageSourceUpdateData(<#CGImageSourceRef isrc#>, <#CFDataRef data#>, <#bool final#>);

生成:CGImageSourceCreateImageAtIndex(<#CGImageSourceRef isrc#>, <#size_t index#>, <#CFDictionaryRef options#>);

返回:return [UIImage imageWithCGImage:imageRef]; 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值