ios ALAsset 通过CGImageWithOptions: 压缩照片技术

 最近在做云相册的功能,把相册的照片上传到云端,但是上传大照片的时候会报内存警告,有时也会发生崩溃现象。比如我的ipod-touch照的一张全景图片有8.3MB,刚要开始上传就报内存警告。我试过通过处理照片把照片把它的宽高各减少一半,然后再上传,但是还会是有内存警告,因为需要把这张照片全部加载到内存才能进行处理。怎么才能避免内存警告是我们接下来讨论的问题

  • 通过查看API找到出路

        上传照片库里的照片,我们需要用到ALAsset这个类,查看其api可以找到如下几个方法来获取图片:

  • - (CGImageRef)thumbnail;

  • - (CGImageRef)aspectRatioThumbnail;

  • [[asset defaultRepresentation] fullResolutionImage];

  • [[asset defaultRepresentation]CGImageWithOptions:(NSDictionary *)options];

        前三个想必很容易理解,可以立马排除掉,剩下的希望就只剩下第四个方法了。但是第四个文档上说的不是很清楚,在苹果的api文档上面搜索也没相应的demo。在百度上搜索CGImageWithOptions,看了好多博客都只是提到了CGImageWithOptions,但是并没有详细介绍其如何应用。然后我又在谷歌上搜索,谷歌上搜索也很少,只有5页搜索结果,经过我自己想拜读各个博客,总算在一个角落里找到了个如何使用的链接,通过链接找到了如何使用的文章。废话不多说了,下面给出代码。


#import <ImageIO/ImageIO.h>
 
// Helper methods for thumbnailForAsset:maxPixelSize:
static  size_t  getAssetBytesCallback( void  *info,  void  *buffer, off_t position,  size_t  count)
 {
     ALAssetRepresentation *rep = (__bridge id)info;
     
     NSError *error = nil;
     size_t  countRead = [rep getBytes:(uint8_t *)buffer fromOffset:position length:count error:&error];
     
     if  (countRead == 0 && error) {
         // We have no way of passing this info back to the caller, so we log it, at least.
         NSLog(@ "thumbnailForAsset:maxPixelSize: got an error reading an asset: %@" , error);
     }
     
     return  countRead;
}
 
static  void  releaseAssetCallback( void  *info)
 {
     // The info here is an ALAssetRepresentation which we CFRetain in thumbnailForAsset:maxPixelSize:.
     // This release balances that retain.
     CFRelease(info);
}
 
// Returns a UIImage for the given asset, with size length at most the passed size.
// The resulting UIImage will be already rotated to UIImageOrientationUp, so its CGImageRef
// can be used directly without additional rotation handling.
// This is done synchronously, so you should call this method on a background queue/thread.

- (UIImage *)thumbnailForAsset:(ALAsset *)asset maxPixelSize:(NSUInteger)size 
{
     NSParameterAssert(asset != nil);
     NSParameterAssert(size > 0);
     
     ALAssetRepresentation *rep = [asset defaultRepresentation];
     
     CGDataProviderDirectCallbacks callbacks =
 {
         .version = 0,
         .getBytePointer = NULL,
         .releaseBytePointer = NULL,
         .getBytesAtPosition = getAssetBytesCallback,
         .releaseInfo = releaseAssetCallback,
  };
     
     CGDataProviderRef provider = CGDataProviderCreateDirect(( void  *)CFBridgingRetain(rep), [rep size], &callbacks);

     CGImageSourceRef source = CGImageSourceCreateWithDataProvider(provider, NULL);
     
     CGImageRef imageRef = CGImageSourceCreateThumbnailAtIndex(source, 0, (__bridge CFDictionaryRef) 
@{     (NSString *)kCGImageSourceCreateThumbnailFromImageAlways : @YES,
      (NSString *)kCGImageSourceThumbnailMaxPixelSize : [NSNumber numberWithInt:size],
      (NSString *)kCGImageSourceCreateThumbnailWithTransform : @YES,
     });

     CFRelease(source);
     CFRelease(provider);
 
     if  (!imageRef) {
         return  nil;
     }
     
     UIImage *toReturn = [UIImage imageWithCGImage:imageRef];
     
     CFRelease(imageRef);
     
     return  toReturn;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值