-
-
Save dezinezync/5b7a4bfe87524e3c11c5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment