문제

I'm trying to use CGImageSourceCreateThumbnailAtIndex to efficiently create a resized version of an image. I have some existing code that does this with images from disk, and now I'm trying to use an image that comes from ALAssetsLibrary.

Here's my code:

ALAsset *asset;
ALAssetRepresentation *representation = [asset defaultRepresentation];
CGImageRef imageRef = [representation fullResolutionImage];

CGDataProviderRef provider = CGImageGetDataProvider(imageRef);
CGImageSourceRef sourceRef = CGImageSourceCreateWithDataProvider(provider, NULL);

NSDictionary *resizeOptions = @{
  kCGImageSourceCreateThumbnailWithTransform : @YES,
  kCGImageSourceCreateThumbnailFromImageAlways : @YES,
  kCGImageSourceThumbnailMaxPixelSize : @(2100) 
};

CGImageRef resizedImage = CGImageSourceCreateThumbnailAtIndex(source, 0, resizeOptions);

The problem is that resizedImage is null, and CGImageSourceGetCount(sourceRef) returns 0. The data provider does have quite a bit of data in it, though, and the data does appear to be valid image data. The ALAsset comes from an iPhone 4S camera roll.

What am I missing? Why does CGImageSourceCreateWithDataProvider() create an image source with 0 images?

도움이 되었습니까?

해결책

CGImageSource is for deserializing serialized images, such as JPEGs, PNGs, and whatnot.

CGImageGetDataProvider returns (the provider of) the raw pixel data of the image. It does not return serialized bytes in some external format. CGImageSource has no way to know what pixel format (color space, bits-per-component, alpha layout, etc.) any given raw pixel data is in.

You could try getting the URL of the asset rep and giving that to CGImageSourceCreateWithURL. If that doesn't work (e.g., not a file URL), you'll have to run the image through a CGImageDestination and create a CGImageSource with wherever you put the output.

(The one other thing to try would be to see whether the rep's filename is actually a full path, the way Cocoa often misuses the term. But you probably shouldn't count on that.)

다른 팁

One thing you might try is the asset rep's CGImageWithOptions: method.

The documentation claims that:

This method returns the biggest, best representation available, unadjusted in any way.

But it says that about fullResolutionImage, too, and I'm not sure why this class would have both methods if they both do the same thing. I wonder if it's a copy-and-paste error.

Try CGImageWithOptions: with a bunch of thumbnail-creating options and see what happens.

Option #3 would be the rep's fullScreenImage. Depending on what sort of “thumbnail” you need, it may be cheaper and/or simpler to just use this, which will be no bigger than (approximately) the size of the device's screen.

This can also help...

ALAssetRepresentation* rep = [asset defaultRepresentation];

NSDictionary* options = [[NSDictionary alloc] initWithObjectsAndKeys:
                     (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform,
                     (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageAlways, 
                     (id)[NSNumber numberWithDouble:400], (id)kCGImageSourceThumbnailMaxPixelSize, 
                     nil];

CGImageRef image = [rep CGImageWithOptions:options];
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top