向CGImageDestinationRef添加/传递(exif)缩略图

8
CGImageDestinationRef苹果参考文献中提到:它可以包含缩略图像以及每个图像的属性。通过在添加图像到CGImageDestinationRef时设置properties参数,属性部分运作良好,但我无法弄清如何添加缩略图。
我想要添加一个缩略图(或直接从CGImageSourceRef传递它)到CGImageDestinationRef,这样当使用CGImageSourceRef打开生成的图像时,我可以使用CGImageSourceCreateThumbnailAtIndex检索原始缩略图。
NSDictionary* thumbOpts = [NSDictionary dictionaryWithObjectsAndKeys:
                                       (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform,
                                       (id)kCFBooleanFalse, (id)kCGImageSourceCreateThumbnailFromImageIfAbsent,
                                       [NSNumber numberWithInt:128], (id)kCGImageSourceThumbnailMaxPixelSize, 
                                       nil];
CGImageRef thumb = CGImageSourceCreateThumbnailAtIndex(iSource, 0, (CFDictionaryRef)thumbOpts);

上面的代码返回拥有缩略图的图像的缩略图,但是当我通过CGImageDestinationRef传递图像时,缩略图丢失了。
是否有一些方法可以保留原始缩略图(或创建新的缩略图)? CGImageProperties Reference似乎没有任何可以存储缩略图的键。
3个回答

1

好的,既然没有人回应(即使是在赏金期间),而且在我花费的时间中尝试通过缩略图,我的猜想是CGImageDestination的文档具有误导性。似乎没有任何(记录的)方法将图像缩略图传递给CGImageDestinationRef(至少不包括OSX 10.7.0和iOS 5.0)。

如果有人持有不同看法,请发布答案,我会接受它(如果它是正确的)。


1

我发现获取缩略图的一种方法是在设置字典中指定kCGImageSourceCreateThumbnailFromImageIfAbsent。

将字典指定为以下内容

NSDictionary* thumbOpts = [NSDictionary dictionaryWithObjectsAndKeys:
                               (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageIfAbsent,
                               (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform,
                               [NSNumber numberWithInt:128], (id)kCGImageSourceThumbnailMaxPixelSize,
                               nil];

更新:如果要向原始的CGImageDestinationRef添加次要(缩略图)图像,请在添加主要图像后执行以下操作

size_t thumbWidth = 640;
size_t thumbHeight = imageHeight / (imageWidth / thumbWidth);
size_t thumbBytesPerRow = thumbWidth * 4;
size_t thumbTotalBytes = thumbBytesPerRow * thumbHeight;
void *thumbData = malloc(thumbTotalBytes);
CGContextRef thumbContext = CGBitmapContextCreate(thumbData,
                                                  thumbWidth,
                                                  thumbHeight,
                                                  8,
                                                  thumbBytesPerRow,
                                                  CGColorSpaceCreateDeviceRGB(),
                                                  kCGImageAlphaNoneSkipFirst);

CGRect thumbRect = CGRectMake(0.f, 0.f, thumbWidth, thumbHeight);
CGContextDrawImage(thumbContext, thumbRect, fullImage);
CGImageRef thumbImage = CGBitmapContextCreateImage(thumbContext);
CGContextRelease(thumbContext);
CGImageDestinationAddImage(destination, thumbImage, nil);
CGImageRelease(thumbImage);

然后为了取回缩略图,请执行以下操作
CFURLRef imageFileURLRef = (__bridge CFURLRef)url;
NSDictionary* sourceOptions = @{(id)kCGImageSourceShouldCache: (id)kCFBooleanFalse,
                                    (id)kCGImageSourceTypeIdentifierHint: (id)kUTTypeTIFF};
CFDictionaryRef sourceOptionsRef = (__bridge CFDictionaryRef)sourceOptions;
CGImageSourceRef imageSource = CGImageSourceCreateWithURL(imageFileURLRef, sourceOptionsRef);
CGImageRef thumb = CGImageSourceCreateImageAtIndex(imageSource, 1, sourceOptionsRef);
UIImage *thumbImage = [[UIImage alloc] initWithCGImage:thumb];
CFRelease(imageSource);
CGImageRelease(thumb);

这段代码基本上与我在问题中添加的获取缩略图的代码相同。该问题询问如何在CGImageDestinationRef中设置缩略图。 - alex-i
CGImageSourceCreateThumbnailAtIndex的选项字典用于从CGImageDestination中获取缩略图。将kCGImageSourceCreateThumbnailFromImageIfAbsent设置为kCFBooleanTrue将在不存在缩略图时创建一个缩略图。如果您正在尝试向CGImageDestination添加缩略图图像,则我的代码片段和您在原始问题中发布的片段都不相关。请查看我的更新答案,了解如何添加缩略图并检索它。 - Nick Mcdonald
这看起来是个不错的解决方法。然而,这仅适用于从我的应用程序中设置和加载缩略图。其他应用程序很可能会尝试获取缓存的缩略图,而不是从索引1读取图像。如果图像容器包含多个图像,则这也可能导致其他问题。 - alex-i

0

在iOS 8.0+上,有一个半文档化的属性可以用于嵌入EXIF缩略图:kCGImageDestinationEmbedThumbnail

苹果的开发者文档是空的,但头文件(CGImageDestination.h)中包含以下注释:

/* Enable or disable thumbnail embedding for JPEG and HEIF.
 * The value should be kCFBooleanTrue or kCFBooleanFalse. Defaults to kCFBooleanFalse */

IMAGEIO_EXTERN const CFStringRef kCGImageDestinationEmbedThumbnail  IMAGEIO_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0);

然而,您无法指定任意缩略图数据,它将自动为您创建。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接