Карта глубины из AVDepthData отличается от данных глубины файла HEIC в Photoshop - PullRequest
0 голосов
/ 13 декабря 2018

Я использую следующий код для извлечения карты глубины (следуя собственному примеру 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) {

}];

Вот результат:это низкое качество (и повернуто, но давайте пока отложим ориентацию) изображение:

enter image description here

Затем я передал оригинальный файл HEIC, открытый вФотошоп, перешел в Каналы и выбрал карту глубины, как показано ниже:

enter image description here

Вот результат:

enter image description here

Это карта с более высоким разрешением / качеством, правильно ориентированная карта глубины.Почему код (на самом деле собственный код Apple на https://developer.apple.com/documentation/avfoundation/avdepthdata/2881221-depthdatafromdictionaryrepresent?language=objc) приводит к снижению качества результата?

1 Ответ

0 голосов
/ 17 декабря 2018

Я нашел проблему.На самом деле, он скрывался на виду.То, что получается из метода +[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.Он позаботился об ориентации.

...