iOS開發(fā)--GIF圖片的選取,壓縮,上傳

之前寫了一篇關(guān)于PNG/JPEG圖片的選取,壓縮,上傳(下邊統(tǒng)一簡(jiǎn)稱前文): http://www.lxweimin.com/p/011b5ef47675, 文本依賴前文的UIImage+ZipSizeAndLength分類進(jìn)行圖片的壓縮等.
總結(jié)一下: 用原生的 UIImagePickerController 選取圖片; 用原生的UIImageJPEGRepresentation()和圖形上下文對(duì)圖片進(jìn)行壓縮; 用AFN進(jìn)行上傳操作.
好了,總結(jié)完之后進(jìn)入今天的主題-----GIF圖片的選取,壓縮,上傳;


目錄:
一 前言
二 選取圖片(重點(diǎn))
三 獲取GIF圖片的原始完整二進(jìn)制數(shù)據(jù)(重點(diǎn))
四 壓縮圖片(重點(diǎn))
五 上傳圖片


一 前言

  有的同學(xué)會(huì)疑惑,難道gif圖片不能用前文說的PNG/JPEG圖片的方法進(jìn)行選取,壓縮和上傳嗎?

我可以肯定的給你回答---不能(自己親身敲代碼做的test,如有疑問,歡迎留言)
原因如下:
1 前文說的選取圖片的代碼如下:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info objectForKey:@"UIImagePickerControllerEditedImage"];
}
對(duì)于GIF圖片只能選取到第一幀,無法取到所有幀.
2 無法取到GIF所有幀,就不能對(duì)圖片進(jìn)行壓縮
3 無法取到GIF所有幀,也不能將圖片轉(zhuǎn)化成二進(jìn)制數(shù)據(jù)
4 沒有二進(jìn)制數(shù)據(jù)就無法進(jìn)行上傳操作
所以需要換另外一個(gè)方法,具體如下.


二 選取圖片
首先判斷是不是GIF圖片,如果是才需要走GIF的邏輯,判斷方法有如下兩種:

第一種(比較取巧):
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *assetString = [[info objectForKey:UIImagePickerControllerReferenceURL] absoluteString];
if([assetString hasSuffix:@"GIF"]){
//這個(gè)圖片是GIF圖片
} else {
}
}
第二種:利用iOS9.0以后出的 Photos/Photos.h 里邊的API進(jìn)行判斷,代碼如下:

NSURL *url = [info objectForKey:UIImagePickerControllerReferenceURL];
PHFetchOptions *options = [[PHFetchOptions alloc]init];
PHFetchResult *set = [PHAsset fetchAssetsWithALAssetURLs:@[url] options:options];
 //轉(zhuǎn)化NSData
PHCachingImageManager *imageManager = [[PHCachingImageManager alloc] init];
PHImageRequestOptions *option = [PHImageRequestOptions new];
option.resizeMode = PHImageRequestOptionsResizeModeFast;
option.synchronous = YES;
PHAsset *asset = set.firstObject;//本文只是選取一張
[imageManager requestImageDataForAsset:asset
               options:option
         resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
                 if ([dataUTI isEqualToString:(__bridge NSString *)kUTTypeGIF]) {
                      //這個(gè)圖片是GIF圖片
                      }else if([dataUTI isEqualToString:(__bridge NSString *)kUTTypePNG]){
                            NSLog(@"PNG圖片");
                      }else if([dataUTI isEqualToString:(__bridge NSString *)kUTTypeJPEG]){
                            NSLog(@"JPEG圖片");
                      }else if([dataUTI isEqualToString:(__bridge NSString *)kUTTypeJPEG2000]){
                            NSLog(@"JPEG2000圖片");
                      }else {
                      }
}];

本文用的是第一種(比較簡(jiǎn)單,效率高)


三 獲取GIF圖片的原始完整二進(jìn)制數(shù)據(jù)(所有幀)
代碼如下:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{      
   NSString *assetString = [[info objectForKey:UIImagePickerControllerReferenceURL] absoluteString];
   if([assetString hasSuffix:@"GIF"]){
       //這個(gè)圖片是GIF圖片
       ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc]init];
       [assetLibrary assetForURL:[info objectForKey:UIImagePickerControllerReferenceURL] resultBlock:^(ALAsset *asset) {
        ALAssetRepresentation *re = [asset representationForUTI:(__bridge NSString *)kUTTypeGIF];;
        NSUInteger size = (NSUInteger)re.size;
        uint8_t *buffer = malloc(size);
        NSError *error;
        NSUInteger bytes = [re getBytes:buffer fromOffset:0 length:size error:&error];
        NSData *data = [NSData dataWithBytes:buffer length:bytes];//這個(gè)就是選取的GIF圖片的原二進(jìn)制數(shù)據(jù)
        free(buffer);
        } failureBlock:^(NSError *error) {
        
    }];
    } else {
   }
}

四 壓縮圖片

利用CoreGraphics/CoreGraphics.h API轉(zhuǎn)換GIF圖片并再次轉(zhuǎn)成符合要求的圖片的二進(jìn)制文件:
封裝方法如下:
+ (NSData *)zipGIFWithData:(NSData *)data {
if (!data) {
return nil;
}
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
size_t count = CGImageSourceGetCount(source);
UIImage *animatedImage = nil;
NSMutableArray *images = [NSMutableArray array];
NSTimeInterval duration = 0.0f;
for (size_t i = 0; i < count; i++) {
CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
duration += [self frameDurationAtIndex:i source:source];
UIImage *ima = [UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
ima = [ima zip];
[images addObject:ima];
CGImageRelease(image);
if (!duration) {
duration = (1.0f / 10.0f) * count;
}
animatedImage = [UIImage animatedImageWithImages:images duration:duration];
}
CFRelease(source);
return UIImagePNGRepresentation(animatedImage);
}
將三種得到的gif圖片的二進(jìn)制數(shù)據(jù)精心壓縮:
代碼如下:

 ....
NSData *data = [NSData dataWithBytes:buffer length:bytes];//這個(gè)就是選取的GIF圖片的原二進(jìn)制數(shù)據(jù)
data = [self zipGIFWithData:data];
//上傳二進(jìn)制數(shù)據(jù)

五 上傳圖片,與前文上傳圖片一樣

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,359評(píng)論 25 708
  • 前段時(shí)間項(xiàng)目中有一個(gè)上傳頭像的需求,對(duì)圖片有一些要求: 圖片不能超過2M,寬高最大為200 并且相等,支持JPG/...
    半緣魔君閱讀 7,674評(píng)論 4 18
  • 前天我去爬山了,今年第一次爬山。在春天爬山還是第一次。春天,真好。天氣那天也相當(dāng)個(gè)給力,大晴天。 爬山的前一天我一...
    空心菜真乖閱讀 156評(píng)論 0 0
  • 第七章《辛福是一種轉(zhuǎn)換力》 每個(gè)人身上都有兩套系統(tǒng),社會(huì)系統(tǒng)(男人)負(fù)責(zé)滿足外界要求,換回生活需求。自我系統(tǒng)(女人...
    丘峻閱讀 436評(píng)論 0 0
  • 今天,我們的生活中充滿了各種各樣的互聯(lián)網(wǎng)產(chǎn)品,在衣食住行的方方面面為我們帶來更便捷更高效的生活體驗(yàn)。作為這些產(chǎn)品的...
    風(fēng)吹麥浪8閱讀 1,289評(píng)論 1 18