I want to build my own depth map and save image like portrait photo with depth info. So first of all I need generate AVDepthData. After dig how it builded, I try to reproduce it:
func buildDepth() {
// ...
let info: [AnyHashable: Any] = [kCGImagePropertyPixelFormat: kCVPixelFormatType_DisparityFloat32,
kCGImagePropertyWidth: width,
kCGImagePropertyHeight: height,
kCGImagePropertyBytesPerRow: bytesPerRow]
let metadata = generateMetadata(photo: photo)
let dic: [AnyHashable: Any] = [kCGImageAuxiliaryDataInfoDataDescription: info,
kCGImageAuxiliaryDataInfoData: data,
kCGImageAuxiliaryDataInfoMetadata: metadata]
guard let depthData = try? AVDepthData(fromDictionaryRepresentation: dic) else {
return false
}
print(depthData.cameraCalibrationData) // <----- prints nil
}
private static func generateMetadata(photo: Photo) -> CGImageMetadata {
let metadata = CGImageMetadataCreateMutable()
let fxy = max(photo.orig.size.width, photo.orig.size.height)
let cx = photo.orig.size.width/2
let cy = photo.orig.size.height/2
addMetadataTag(metadata, key: "Filtered", value: true)
addMetadataTag(metadata, key: "Quality", value: "high")
addMetadataTag(metadata, key: "Accuracy", value: "relative")
addMetadataTag(metadata, key: "DepthDataVersion", value: 65538)
addMetadataTag(metadata, key: "PixelSize", value: 0.001000)
addMetadataTag(metadata, key: "LensDistortionCoefficients", value: [0,0,0,0,0,0,0,0])
addMetadataTag(metadata, key: "InverseLensDistortionCoefficients", value: [0,0,0,0,0,0,0,0])
addMetadataTag(metadata, key: "IntrinsicMatrixReferenceWidth", value: photo.orig.size.width)
addMetadataTag(metadata, key: "IntrinsicMatrixReferenceHeight", value: photo.orig.size.height)
addMetadataTag(metadata, key: "LensDistortionCenterOffsetX", value: cx)
addMetadataTag(metadata, key: "LensDistortionCenterOffsetY", value: cy)
addMetadataTag(metadata, key: "ExtrinsicMatrix", value: [1,0,0,
0,1,0,
0,0,1,
0,0,0])
addMetadataTag(metadata, key: "IntrinsicMatrix", value: [fxy,0,0,
0,fxy,0,
cx,cy,1])
addMetadataTag(metadata, type: .depthBlur, key: "SimulatedAperture", value: 4.5)
addMetadataTag(metadata, type: .depthBlur, key: "RenderingParameters", value: "UkVORAEAAAAwAAAAAgAAAJqZmT4K1yM8F0iSOTVeuj0zM7M/DdXOOwAAAD+amRk+")
print(metadata)
return metadata
}
enum MetadataType {
case depth, depthBlur
}
@discardableResult private static func addMetadataTag(_ metadata: CGMutableImageMetadata, type: MetadataType = .depth, key: String, value: Any) -> Bool {
let namespace: String
let prefix: String
switch type {
case .depth:
namespace = "http://ns.apple.com/depthData/1.0/"
prefix = "depthData"
case .depthBlur:
namespace = "http://ns.apple.com/depthBlurEffect/1.0/"
prefix = "depthBlurEffect"
}
guard let metadataTag = CGImageMetadataTagCreate(namespace as CFString, prefix as CFString, key as CFString, .default, value as CFTypeRef)
else { return false }
print("type", CGImageMetadataTagGetType(metadataTag).rawValue)
return CGImageMetadataSetTagWithPath(metadata, nil, ("xmp:"+key) as CFString, metadataTag)
}
After this I get AVDepthData
witch I can save into image. But this data not contains any additional info like cameraCalibrationData
. Dictionary generated by system looks similar to my dictionary.