获取fullResolutionImage时应用程序崩溃

时间:2012-01-17 13:05:20

标签: iphone objective-c

我尝试使用我的应用ALAssetRepresentation。当我循环显示图片时,有几张图片会让应用崩溃

for(ALAsset *asset in _assets) {
        NSMutableDictionary *workingDictionary = [[NSMutableDictionary alloc] init];
        [workingDictionary setObject:[asset valueForProperty:ALAssetPropertyType] forKey:@"UIImagePickerControllerMediaType"];

        ALAssetRepresentation *representation = [asset defaultRepresentation];

        if (!representation) {
            [workingDictionary release];
            continue;
        }
        CGImageRef imageRef = [representation fullResolutionImage];//here the app crash
            UIImage *img = [UIImage imageWithCGImage:imageRef];
    if (!img) {
        [workingDictionary release];
        continue;
    }
    if (!img) {
        [workingDictionary release];
        continue;
    }

    [workingDictionary setObject:img forKey:@"UIImagePickerControllerOriginalImage"];
    [workingDictionary setObject:[asset valueForProperty:ALAssetPropertyOrientation] forKey:@"orientation"];

    [returnArray addObject:workingDictionary];
    [workingDictionary release];    
}

在这一行中我没有任何消息而崩溃:

CGImageRef imageRef = [representation fullResolutionImage];

这是崩溃信息

    Program received signal:  “0”.
Data Formatters temporarily unavailable, will re-try after a 'continue'. (Unknown error loading shared library "/Developer/usr/lib/libXcodeDebuggerSupport.dylib")

2 个答案:

答案 0 :(得分:1)

这很可能是因为内存耗尽,导致崩溃的图像有多大?

答案 1 :(得分:0)

我遇到了类似的问题,经过几个小时的寻找解决方案,我发现了这个 - 太大资产错误的最佳解决方案:

// For details, see http://mindsea.com/2012/12/18/downscaling-huge-alassets-without-fear-of-sigkill

#import <AssetsLibrary/AssetsLibrary.h>
#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;
}