最近發(fā)現(xiàn)相冊可以直接存儲疆偿、瀏覽 gif,感覺蘋果開始注意 gif彼妻,所以總結一下自己的使用方法嫌佑。一般 gif 在內存比較大豆茫,在 cell 上展示會比較卡,所以做下壓縮還是很有必要的屋摇。查找很多資料也沒法下可以直接操作的 api揩魂,所有的壓縮原理似乎都是對 gif 的每幀圖片分別壓縮,然后再合成 gif炮温,所以我也是按照這個思路實現(xiàn)了一下火脉。下面直接上代碼:
+ (NSData *)scallGIFWithData:(NSData *)data scallSize:(CGSize)scallSize {
if (!data) {
return nil;
}
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
size_t count = CGImageSourceGetCount(source);
// 設置 gif 文件屬性 (0:無限次循環(huán))
NSDictionary *fileProperties = [self filePropertiesWithLoopCount:0];
NSString *tempFile = [NSTemporaryDirectory() stringByAppendingString:@"scallTemp.gif"];
NSFileManager *manager = [NSFileManager defaultManager];
if ([manager fileExistsAtPath:tempFile]) {
[manager removeItemAtPath:tempFile error:nil];
}
NSURL *fileUrl = [NSURL fileURLWithPath:tempFile];
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileUrl, kUTTypeGIF , count, NULL);
NSTimeInterval duration = 0.0f;
for (size_t i = 0; i < count; i++) {
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, i, NULL);
UIImage *image = [UIImage imageWithCGImage:imageRef];
UIImage *scallImage = [self scallImageWidthScallSize:scallSize];
NSTimeInterval delayTime = [self frameDurationAtIndex:i source:source];
duration += delayTime;
// 設置 gif 每針畫面屬性
NSDictionary *frameProperties = [self framePropertiesWithDelayTime:delayTime];
CGImageDestinationAddImage(destination, scallImage.CGImage, (CFDictionaryRef)frameProperties);
CGImageRelease(imageRef);
}
CGImageDestinationSetProperties(destination, (CFDictionaryRef)fileProperties);
// Finalize the GIF
if (!CGImageDestinationFinalize(destination)) {
NSLog(@"Failed to finalize GIF destination");
if (destination != nil) {
CFRelease(destination);
}
return nil;
}
CFRelease(destination);
CFRelease(source);
return [NSData dataWithContentsOfFile:tempFile];
}
按照 size 壓縮每幀圖片
- (UIImage *)scallImageWidthScallSize:(CGSize)scallSize{
CGFloat width = self.size.width;
CGFloat height = self.size.height;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = scallSize.width;
CGFloat scaledHeight = scallSize.height;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
if (!CGSizeEqualToSize(self.size, scallSize))
{
CGFloat widthFactor = scaledWidth / width;
CGFloat heightFactor = scaledHeight / height;
scaleFactor = MAX(widthFactor, heightFactor);
scaledWidth= width * scaleFactor;
scaledHeight = height * scaleFactor;
// center the image
if (widthFactor > heightFactor)
{
thumbnailPoint.y = (scallSize.height - scaledHeight) * 0.5;
}
else if (widthFactor < heightFactor)
{
thumbnailPoint.x = (scallSize.width - scaledWidth) * 0.5;
}
}
CGRect rect;
rect.origin = thumbnailPoint;
rect.size = CGSizeMake(scaledWidth, scaledHeight);
UIGraphicsBeginImageContext(rect.size);
[self drawInRect:rect];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
讀取幀率
+ (float)frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {
float frameDuration = 0.1f;
CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;
NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary];
NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
if (delayTimeUnclampedProp) {
frameDuration = [delayTimeUnclampedProp floatValue];
}
else {
NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];
if (delayTimeProp) {
frameDuration = [delayTimeProp floatValue];
}
}
if (frameDuration < 0.011f) {
frameDuration = 0.100f;
}
CFRelease(cfFrameProperties);
frameDuration += 0.1;
return frameDuration;
}
合成新的 gif, 設置播放屬性
+ (NSDictionary *)filePropertiesWithLoopCount:(int)loopCount {
return @{(NSString *)kCGImagePropertyGIFDictionary:
@{(NSString *)kCGImagePropertyGIFLoopCount: @(loopCount)}
};
}
+ (NSDictionary *)framePropertiesWithDelayTime:(NSTimeInterval)delayTime {
return @{(NSString *)kCGImagePropertyGIFDictionary:
@{(NSString *)kCGImagePropertyGIFDelayTime: @(delayTime)},
(NSString *)kCGImagePropertyColorModel:(NSString *)kCGImagePropertyColorModelRGB
};
}