CGImageSource的用法

来源:互联网 发布:mac哑光橘红色 编辑:程序博客网 时间:2024/05/29 12:02
导入ImageIO.framework
#import 
<ImageIO/ImageIO.h> 

1.创建CGImageSourceRef
1
2
NSString *imagePath=[[NSBundlebundleForClass:self.class]pathForImageResource:@"test.png"];
CGImageSourceRefimageSource=CGImageSourceCreateWithURL((__bridgeCFURLRef)[NSURLfileURLWithPath:imagePath],NULL);
2.获取图像
CGImageRefimageRef=CGImageSourceCreateImageAtIndex(imageSource,0,NULL);
3.创建图像的缩略图

//缩略图的宽和高
 
doublethumbnailWidth=xxx,thumbnailHeight=xxx;
 
//缩略图的信息的字典
 
NSDictionary *thumbnailInfo=@{
 
(NSString *)kCGImageSourceCreateThumbnailFromImageAlways:@YES,
 
(NSString *)kCGImageSourceThumbnailMaxPixelSize:[NSNumbernumberWithInt:MAX(thumbnailWidth,thumbnailHeight)],
 
(NSString *)kCGImageSourceCreateThumbnailWithTransform:@YES,
 
};
 
//得到缩略图
 
CGImageRefimageRef=CGImageSourceCreateThumbnailAtIndex(imageSource,0,(__bridgeCFDictionaryRef)thumbnailInfo);

4.获取图像的属性信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CFDictionaryRefimageInfo=CGImageSourceCopyPropertiesAtIndex(imageSource,0,NULL);
 
//像素的宽
 
NSNumber *pixelWidthObj=(__bridgeNSNumber *)CFDictionaryGetValue(imageInfo,kCGImagePropertyPixelWidth);
 
//像素的高
 
NSNumber *pixelHeightObj=(__bridgeNSNumber *)CFDictionaryGetValue(imageInfo,kCGImagePropertyPixelHeight);
 
//图像的旋转方向
 
NSIntegerorientation=[(__bridgeNSNumber *)CFDictionaryGetValue(imageInfo,kCGImagePropertyOrientation)integerValue];
 //时间间隔
NSNumber *number = fromCFCFDictionaryGetValue(gifProperties,kCGImagePropertyGIFUnclampedDelayTime); 
//Exif信息
 
NSDictionary *exifInfo=(__bridgeNSDictionary *)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库就是根据先行下载的图片头,构建一个空白图片(其实工作量很多,包括各种图片类型、数据等解码,然后空白图和已有数据编码成一个图片),然后新来的多少数据边覆盖空白部分,直到最后完成。 
 
创建:CGImageSourceRefimageSource= CGImageSourceCreateIncremental(NULL);

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

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

返回:return [UIImage imageWithCGImage:imageRef]; 

0 0