|
[Objective-C] Thumbnail image from ALAsset with a category |
|
 |
#import <AssetsLibrary/AssetsLibrary.h>
#import <AVFoundation/AVFoundation.h>
#import <ImageIO/ImageIO.h>
@interface ALAsset (Thumbnail)
- (UIImage*)thumbnailImageSize:(int)size;
@end
@implementation ALAsset (Thumbnail)
typedef struct {
void *assetRepresentation;
int decodingIterationCount;
} ThumbnailDecodingContext;
static const int kThumbnailDecodingContextMaxIterationCount = 16;
static size_t getAssetBytesCallback(void *info, void *buffer, off_t position, size_t count)
{
ThumbnailDecodingContext *decodingContext = (ThumbnailDecodingContext *)info;
ALAssetRepresentation *assetRepresentation = (__bridge ALAssetRepresentation *)decodingContext->assetRepresentation;
if (decodingContext->decodingIterationCount == kThumbnailDecodingContextMaxIterationCount) {
NSLog(@"WARNING: Image %@ is too large for thumbnail extraction.", [assetRepresentation url]);
return 0;
}
++decodingContext->decodingIterationCount;
NSError *error = nil;
size_t countRead = [assetRepresentation getBytes:(uint8_t *)buffer fromOffset:position length:count error:&error];
if (countRead == 0 || error != nil) {
NSLog(@"ERROR: Failed to decode image %@: %@", [assetRepresentation url], error);
return 0;
}
return countRead;
}
- (UIImage*)thumbnailImageSize:(int)size
{
if ([[self valueForProperty:@"ALAssetPropertyType"] isEqualToString:@"ALAssetTypePhoto"]) {
CGDataProviderDirectCallbacks callbacks = {
.version = 0,
.getBytePointer = NULL,
.releaseBytePointer = NULL,
.getBytesAtPosition = getAssetBytesCallback,
.releaseInfo = NULL
};
ThumbnailDecodingContext decodingContext = {
.assetRepresentation = (__bridge void *)self.defaultRepresentation,
.decodingIterationCount = 0
};
CGDataProviderRef provider = CGDataProviderCreateDirect((void *)&decodingContext,
[self.defaultRepresentation size], &callbacks);
if (!provider)
return nil;
CGImageSourceRef source = CGImageSourceCreateWithDataProvider(provider, NULL);
if (!source) {
CGDataProviderRelease(provider);
return nil;
}
CFDictionaryRef options = (__bridge CFDictionaryRef) @{
(id) kCGImageSourceCreateThumbnailWithTransform : @YES,
(id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
(id) kCGImageSourceThumbnailMaxPixelSize : @(size)};
CGImageRef imageRef = CGImageSourceCreateThumbnailAtIndex(imageSourceRef, 0, options);
if (!imageRef) {
return nil;
}
UIImage *image = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CFRelease(source);
CGDataProviderRelease(provider);
return image;
}
@end
|
|
|
|
|
|
|
|
Copyright © 1996-2021 Centro Studi Informatica di Danilo Priore. All rights reserved. P.I.10149810581. |
|
|
|