добавить / передать (exif) миниатюру в CGImageDestinationRef - PullRequest
6 голосов
/ 03 января 2012

Вкл. CGImageDestinationRef Ссылка Apple упоминает, что It can contain thumbnail images as well as properties for each image. Деталь со свойствами работает хорошо, устанавливая параметр 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 , похоже, не имеет ключей для хранения миниатюры.

Ответы [ 3 ]

1 голос
/ 29 апреля 2015

Я нашел способ вернуть миниатюру одним способом - указать 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);
1 голос
/ 13 января 2012

Хорошо, так как никто не ответил (даже во время щедрости), плюс после нескольких часов, которые я потратил, пытаясь передать миниатюру, я предполагаю, что документация для CGImageDestination вводит в заблуждение.Кажется, нет никакого (документированного) способа передать миниатюру изображения в CGImageDestinationRef (по крайней мере, не до, включая OSX 10.7.0 и iOS 5.0).

Если кто-то думает иначе, оставьте ответ, и я его приму (если он правильный).

0 голосов
/ 18 июня 2018

Существует полудокументированное свойство для встраивания миниатюр EXIF ​​на iOS 8.0+: 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);

Однако вы не можете указать произвольные данные большого пальца, они будут автоматически созданы для вас.

...