这个问题我只询问了在Xcode和iOS中没有外部库的情况下可能性。我已经在另一个问题中探索使用libtiff
的可能性。
问题
我已经在Stack Overflow上筛选了数周,并找到了每个问题的可行解决方案。我有4个需要解决的问题:
- 我需要从相机获取RGBA数据,不进行任何压缩
- 我需要尽可能多的元数据,特别是EXIF
- 我需要以TIFF格式保存,以便与其他软件兼容并保持无损
- 我需要通过保存在文件而不是照片库中来保护免受随意查看
通过使用JPEG,我可以满足2和4。 通过从相机缓冲区制作原始数据(分别为NSData),我可以满足1、3和4。 在Xcode和iOS中,我是否能够满足所有4个先决条件?我即将放弃,寻求您作为最后一种选择的建议。
虽然我还在探索中,但我也陷入了我尝试的另一条路libtiff。不过我仍在努力...
这是我尝试过的伟大建议列表,我的代码只是从像这样的stackoverflow来源组合而成:
- 如何将Exif元数据写入图像(不是相机滚动条,只是UIImage或JPEG)(让我希望我能使用JPEG格式,在做Apple喜欢的事情时非常轻松)
- 来自像“645 PRO”这样的相机的原始图像数据(这将是使用libtiff等)的点
- 将CGImageRef保存为png文件?(也可以使用
kUTTypeTIFF
,但没有元数据)
解决方案
从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提供的帮助!
UICollectionView
中显示缩略图)? - AOphagen