Карта глубины из AVDepthData отличается от данных глубины файла HEIC в Photoshop
Я использую следующий код для извлечения карты глубины (следуя собственному примеру Apple):
- (nullable AVDepthData *)depthDataFromImageData:(nonnull NSData *)imageData orientation:(CGImagePropertyOrientation)orientation {
AVDepthData *depthData = nil;
CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef)imageData, NULL);
if (imageSource) {
NSDictionary *auxDataDictionary = (__bridge NSDictionary *)CGImageSourceCopyAuxiliaryDataInfoAtIndex(imageSource, 0, kCGImageAuxiliaryDataTypeDisparity);
if (auxDataDictionary) {
depthData = [[AVDepthData depthDataFromDictionaryRepresentation:auxDataDictionary error:NULL] depthDataByApplyingExifOrientation:orientation];
}
CFRelease(imageSource);
}
return depthData;
}
И я называю это от:
[[PHAssetResourceManager defaultManager] requestDataForAssetResource:[PHAssetResource assetResourcesForAsset:asset].firstObject options:nil dataReceivedHandler:^(NSData * _Nonnull data) {
AVDepthData *depthData = [self depthDataFromImageData:data orientation:[self CGImagePropertyOrientationForUIImageOrientation:pickedUiImageOrientation]];
CIImage *image = [CIImage imageWithDepthData:depthData];
UIImage *uiImage = [UIImage imageWithCIImage:image];
UIGraphicsBeginImageContext(uiImage.size);
[uiImage drawInRect:CGRectMake(0, 0, uiImage.size.width, uiImage.size.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *pngData = UIImagePNGRepresentation(newImage);
UIImage* pngImage = [UIImage imageWithData:pngData]; // rewrap
UIImageWriteToSavedPhotosAlbum(pngImage, nil, nil, nil);
} completionHandler:^(NSError * _Nullable error) {
}];
Вот результат: это изображение низкого качества (и повернутое, но давайте пока отложим ориентацию):
Затем я перенес исходный файл HEIC, открыл его в Photoshop, перешел на каналы и выбрал карту глубины, как показано ниже:
Вот результат:
Это более высокое разрешение / качество, правильно ориентированная карта глубины. Почему код (фактически собственный код Apple по адресу https://developer.apple.com/documentation/avfoundation/avdepthdata/2881221-depthdatafromdictionaryrepresent?language=objc) приводит к снижению качества результата?
1 ответ
Я нашел проблему. На самом деле, он скрывался на виду. Что получается из +[AVDepthData depthDataFromDictionaryRepresentation:error:]
метод возвращает данные о несоответствии. Я преобразовал его в глубину, используя следующий код:
if(depthData.depthDataType != kCVPixelFormatType_DepthFloat32){
depthData = [depthData depthDataByConvertingToDepthDataType:kCVPixelFormatType_DepthFloat32];
}
(Не пробовал, но 16-битная глубина, kCVPixelFormatType_DepthFloat16
, тоже должно хорошо сработать)
После преобразования несоответствия в глубину изображение точно такое же, как в Photoshop. Я должен был проснуться, как я использовал CGImageSourceCopyAuxiliaryDataInfoAtIndex(imageSource, 0, kCGImageAuxiliaryDataTypeDisparity);
(обратите внимание на "несоответствие" в конце), и Photoshop четко говорил "карта глубины", преобразуя несоответствие в глубину (или просто считывая глубину, я, честно говоря, не знаю физического кодирования, возможно, iOS преобразовывала глубину в несоответствие, когда Я копировал вспомогательные данные в первую очередь) на лету.
Примечание: я также решил проблему ориентации, создав источник изображения непосредственно из [PHAsset requestContentEditingInputWithOptions:completionHandler:]
метод и прохождение contentEditingInput.fullSizeImageURL
в CGImageSourceCreateWithURL
метод. Он позаботился об ориентации.