Resizing CMSampleBufferRef provided by captureStillImageBracketAsynchronouslyFromConnection:withSettingsArray:completionHandler:

China☆狼群 提交于 2019-12-24 11:35:46

问题


In the app I'm working on, we're capturing photos which need to have 4:3 aspect ratio in order to maximize the field of view we capture. Up untill now we were using AVCaptureSessionPreset640x480 preset, but now we're in need of larger resolution.

As far as I've figured, the only other two 4:3 formats are 2592x1936 and 3264x2448. Since these are too large for our use case, I need a way to downsize them. I looked into a bunch of options but did not find a way (prefereably without copying the data) to do this in an efficient manner without losing the exif data.

vImage was one of the things I looked into but as far as I've figured the data would need to be coppied and the exif data would be lost. Another option was creating an UIImage from data provided by jpegStillImageNSDataRepresentation, scaling it and getting the data back. This approach also seems to strip the exif data.

The ideal approach here would be resizing the buffer contents directly and resizing the photo. Does anyone have an idea how I would go about doing this?


回答1:


I ended up using ImageIO for resizing purposes. Leaving this piece of code here in case someone runs into the same problem, as I've spent way too much time on this.

This code will preserve the exif data, but will create a copy of the image data. I ran some benchmarks - the execution time for this method is ~0.05sec on iPhone6, using AVCaptureSessionPresetPhoto as the preset for the original photo.

If someone does have a more optimal solution, please leave a comment.

- (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;
}


来源:https://stackoverflow.com/questions/32972429/resizing-cmsamplebufferref-provided-by-capturestillimagebracketasynchronouslyfro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!