2015-10-06 2 views
1

В приложении, над которым я работаю, мы собираем фотографии, которые должны иметь соотношение сторон 4: 3, чтобы максимизировать поле обзора, которое мы снимаем. До сих пор мы использовали AVCaptureSessionPreset640x480 пресет, но теперь нам нужно большее разрешение.Изменение размера CMSampleBufferRef обеспечивается captureStillImageBracketAsynchronouslyFromConnection: withSettingsArray: completeHandler:

Насколько я понял, единственными двумя форматами 4: 3 являются 2592x1936 и 3264x2448. Поскольку они слишком велики для нашего случая использования, мне нужен способ уменьшить их. Я просмотрел множество опций, но не нашел способ (предпочтительно без копирования данных), чтобы сделать это эффективным образом, не теряя данные exif.

vImage был одной из вещей, которые я изучил, но насколько я понял, данные должны быть скопированы, а данные exif будут потеряны. Другим вариантом было создание UIImage из данных, предоставленных jpegStillImageNSDataRepresentation, масштабирование и возврат данных. Этот подход также, похоже, лишает данные exif.

Идеальный подход здесь будет изменять размер содержимого буфера напрямую и изменить размер фотографии. Кто-нибудь есть идея, как я буду заниматься этим?

ответ

0

В результате я использовал ImageIO для изменения размера. Оставляя этот фрагмент кода здесь, если кто-то сталкивается с той же проблемой, поскольку я потратил слишком много времени на это.

Этот код сохранит данные exif, но создаст копию данных изображения. Я провел несколько тестов - время выполнения этого метода составляет ~ 0,05 с на iPhone6, используя AVCaptureSessionPresetPhoto в качестве предустановки для исходной фотографии.

Если у кого-то есть более оптимальное решение, оставьте комментарий.

- (NSData *)resizeJpgData:(NSData *)jpgData 
{ 
    CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)jpgData, NULL); 

    // Create a copy of the metadata that we'll attach to the resized image 
    NSDictionary *metadata = (NSDictionary *)CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(source, 0, NULL)); 
    NSMutableDictionary *metadataAsMutable = [metadata mutableCopy]; 

    // Type of the image (e.g. public.jpeg) 
    CFStringRef UTI = CGImageSourceGetType(source); 

    NSDictionary *options = @{ (id)kCGImageSourceCreateThumbnailFromImageIfAbsent: (id)kCFBooleanTrue, 
           (id)kCGImageSourceThumbnailMaxPixelSize: @(MAX(FORMAT_WIDTH, FORMAT_HEIGHT)), 
           (id)kCGImageSourceTypeIdentifierHint: (__bridge NSString *)UTI }; 
    CGImageRef resizedImage = CGImageSourceCreateThumbnailAtIndex(source, 0, (CFDictionaryRef)options); 

    NSMutableData *destData = [NSMutableData data]; 
    CGImageDestinationRef destination = CGImageDestinationCreateWithData((CFMutableDataRef)destData, UTI, 1, NULL); 
    if (!destination) { 
     NSLog(@"Could not create image destination"); 
    } 

    CGImageDestinationAddImage(destination, resizedImage, (__bridge CFDictionaryRef) metadataAsMutable); 

    // Tell the destination to write the image data and metadata into our data object 
    BOOL success = CGImageDestinationFinalize(destination); 
    if (!success) { 
     NSLog(@"Could not create data from image destination"); 
    } 

    if (destination) { 
     CFRelease(destination); 
    } 
    CGImageRelease(resizedImage); 
    CFRelease(source); 

    return destData; 
} 
Смежные вопросы