调整captureStillImageBracketAsynchronouslyFromConnection:withSettingsArray:completionHandler提供的CMSampleBufferRef的大小: [英] Resizing CMSampleBufferRef provided by captureStillImageBracketAsynchronouslyFromConnection:withSettingsArray:completionHandler:

查看:211
本文介绍了调整captureStillImageBracketAsynchronouslyFromConnection:withSettingsArray:completionHandler提供的CMSampleBufferRef的大小:的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我正在开发的应用程序中,我们正在捕获需要具有4:3纵横比的照片,以最大程度地捕获我们捕获的视野.到目前为止,我们一直使用AVCaptureSessionPreset640x480预设,但是现在我们需要更大的分辨率.

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.

据我所知,仅有的另外两种4:3格式是2592x1936和3264x2448.由于这些对于我们的用例来说太大了,我需要一种减小它们尺寸的方法.我研究了很多选项,但没有找到一种方法(最好是不复制数据)来有效地做到这一点,而又不会丢失exif数据.

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是我研究过的内容之一,但据我所知,数据需要复制,而exif数据将丢失.另一种选择是根据jpegStillImageNSDataRepresentation提供的数据创建UIImage,对其进行缩放并取回数据.这种方法似乎也剥夺了exif数据.

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?

推荐答案

我最终使用ImageIO进行大小调整.将这段代码留在这里,以防有人遇到相同的问题,因为我在此上花了太多时间.

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.

此代码将保留exif数据,但将创建图像数据的副本.我运行了一些基准测试-使用AVCaptureSessionPresetPhoto作为原始照片的预设,该方法在iPhone6上的执行时间约为0.05秒.

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

这篇关于调整captureStillImageBracketAsynchronouslyFromConnection:withSettingsArray:completionHandler提供的CMSampleBufferRef的大小:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆