#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
)
;
|
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];