gpt4 book ai didi

avfoundation - 如何将来自 AVFoundations captureStillImageAsynchronouslyFromConnection 的 TIFF 照片保存到 iPhone (iOS) 上带有 EXIF 元数据的文件中?

转载 作者:行者123 更新时间:2023-12-04 02:52:35 28 4
gpt4 key购买 nike

对于这个问题,我只询问在没有外部库的情况下使用 Xcode 和 iOS 的可能性。我已经在探索在另一个 question 中使用 libtiff 的可能性.

问题

数周以来,我一直在筛选堆栈溢出,并为我的每一个问题找到了可行的解决方案。我有 4 件事需要工作:

  1. 我需要来自相机的 RGBA 数据,没有任何压缩
  2. 我需要尽可能多的元数据,尤其是 EXIF
  3. 我需要以 TIFF 格式保存以与其他软件兼容和无损
  4. 我需要通过保存在文件而不是照片库中来防止随意查看

我可以使用 JPEG 得到 2 和 4。我可以将 1、3 和 4 与从相机缓冲区制作的原始数据(分别为 NSData)一起使用。我可以通过 Xcode 和 iOS 满足所有 4 个先决条件吗?我即将放弃并寻找您的意见作为最后的手段。

虽然仍在探索这个问题,但我也停留在我尝试过的另一条途径上,libtiff .不过我还在努力……

这是我尝试过的重要建议的列表,我自己的代码只是从这些堆栈溢出源中拼凑而成:

解决方案

captureStillImageAsynchronouslyFromConnection 的完整操作序列:

[[self myAVCaptureStillImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error)
{
//get all the metadata in the image
CFDictionaryRef metadata = CMCopyDictionaryOfAttachments(kCFAllocatorDefault, imageSampleBuffer, kCMAttachmentMode_ShouldPropagate);
// get image reference
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(imageSampleBuffer);
// >>>>>>>>>> lock buffer address
CVPixelBufferLockBaseAddress(imageBuffer, 0);

//Get information about the image
uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);

// create suitable color space
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

//Create suitable context (suitable for camera output setting kCVPixelFormatType_32BGRA)
CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);

// <<<<<<<<<< unlock buffer address
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);

// release color space
CGColorSpaceRelease(colorSpace);

//Create a CGImageRef from the CVImageBufferRef
CGImageRef newImage = CGBitmapContextCreateImage(newContext);

// release context
CGContextRelease(newContext);

// create destination and write image with metadata
CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:filePath isDirectory:NO];
CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypeTIFF, 1, NULL);
CGImageDestinationAddImage(destination, imageRef, metadata);

// finalize and release destination
CGImageDestinationFinalize(destination);
CFRelease(destination);
}

静态图像输出相关的相机设置是:

[[self myAVCaptureSession] setSessionPreset:AVCaptureSessionPresetPhoto];

NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], (id)kCVPixelBufferPixelFormatTypeKey, nil];
[myAVCaptureStillImageOutput setOutputSettings:outputSettings];

我得到了一张标称 TIFF 格式的标称未压缩图像,其中包含所有元数据。 (它在其他系统上有镜像,但现在我可以编写 EXIF 和其他元数据,我也可以对其进行微调,我确信)。

再次感谢 Wildaker感谢他的帮助!

最佳答案

由于您已经破解了 1、3 和 4,看来您缺少的唯一障碍是将数据和元数据保存在一起。试试这个(假设未处理的数据在名为 myImageDataSampleBufferCMSampleBufferRef 中,并且您已经完成了将图形数据放入 CGImageRef 的繁重工作称为 myImage):

CFDictionaryRef metadata = CMCopyDictionaryOfAttachments(kCFAllocatorDefault,
myImageDataSampleBuffer,
kCMAttachmentMode_ShouldPropagate);
NSFileManager* fm = [[NSFileManager alloc] init];
NSURL* pathUrl = [fm URLForDirectory:saveDir
inDomain:NSUserDomainMask
appropriateForURL:nil
create:YES
error:nil];
NSURL* saveUrl = [pathUrl URLByAppendingPathComponent:@"myfilename.tif"];
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)saveUrl,
(CFStringRef)@"public.tiff", 1, NULL);
CGImageDestinationAddImage(destination, myImage, metadata);
CGImageDestinationFinalize(destination);
CFRelease(destination);

关于avfoundation - 如何将来自 AVFoundations captureStillImageAsynchronouslyFromConnection 的 TIFF 照片保存到 iPhone (iOS) 上带有 EXIF 元数据的文件中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17361100/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com