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

发布于 2024-12-24 02:38:37 字数 1427 浏览 3 评论 0原文

CGImageDestinationRef Apple 的参考中提到它可以包含缩略图以及每个图像的属性。 通过在添加属性时设置 properties 参数,具有属性的部分效果很好。图像到 CGImageDestinationRef,但我不知道如何添加缩略图。

我想将缩略图(或直接从 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 似乎没有任何存储缩略图的键。

On CGImageDestinationRef Apple's reference it mentions that It can contain thumbnail images as well as properties for each image. The part with the properties works nice, by setting the properties parameter when adding a image to the CGImageDestinationRef, but I can't figure out how to add the thumbnail.

I want to add a thumbnail (or pass it directly from a CGImageSourceRef) to CGImageDestinationRef, such that when the resulting image is opened with CGImageSourceRef I can use CGImageSourceCreateThumbnailAtIndex to retrieve the original thumbnail.

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);

The code above returns the thumbnail of the images that have it stored, but when I pass the image through CGImageDestinationRef, the thumbnail is lost.

Is there some way to keep the original thumbnail (or create a new one)? CGImageProperties Reference doesn't seem to have any keys where to store the thumbnail.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

亣腦蒛氧 2024-12-31 02:38:37

我发现获取缩略图的一种方法是在设置字典中指定 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);

One way I've found to get a thumbnail back is to specify kCGImageSourceCreateThumbnailFromImageIfAbsent in the settings dictionary.

Specify the dictionary as follows

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

Update: In order to add a secondary (thumbnail) image to the original CGImageDestinationRef do the following after you've added the primary image

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);

Then in order to get the thumbnail back out, do the following

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);
苄①跕圉湢 2024-12-31 02:38:37

好吧,既然没有人回应(即使在赏金期间),再加上我花了几个小时试图传递缩略图,我的猜测是 CGImageDestination 的文档具有误导性。似乎没有任何(已记录的)方法将图像缩略图传递到 CGImageDestinationRef (至少不包括 OSX 10.7.0 和 iOS 5.0)。

如果有人不这么认为,请发布答案,我会接受它(如果它是正确的)。

Ok, so since no one responded (even during bounty), plus after the hours I spent trying to pass the thumbnail, my guess is that the documentation for CGImageDestination is misleading. There doesn't seem to be any (documented) way to pass the image thumbnail to a CGImageDestinationRef (atleast not up to, and including, OSX 10.7.0 and iOS 5.0).

If anyone thinks otherwise, post an answer and I'll accept it (if it's correct).

随心而道 2024-12-31 02:38:37

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

Apple 的开发文档是空的,但头文件 (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);

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

There is a half-documented property for embedding EXIF thumbnails on iOS 8.0+: kCGImageDestinationEmbedThumbnail.

Apple's developer doc is empty, but the header file (CGImageDestination.h) contains the following comment:

/* 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);

However you can't specify arbitrary thumbail data, it will get automatically created for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文