objc, сохраните изображение с параметром экспозиции в альбом

Я отчаянно борюсь с этим вопросом...

Фон: у меня есть приложение, которое делает 4 снимка в одном затворе с разной экспозицией, для которого установлено значение AVCapturePhotoBracketSettings. Я преобразовал CMSampleBufferRef в UIImage* и сохранить их в мой фотоальбом, позвонив

UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);// image is UIImage*

Но позже, когда я экспортировал изображения в мой Mac, я понял, что все параметры экспозиции проверены, щелкнув правой кнопкой мыши изображение -> Получить информацию. У меня NSArray хранит 4 экспозиции. Я хочу поместить их в UIImage по одному для каждого, поэтому после сохранения их в моем альбоме он может показывать время экспозиции в Get Info, точно так же, как показывает изображение в альбоме, если я взял его со встроенной камеры iphone.


Проблема: у меня есть 3 длины 4 NSMutableArrays. Один хранит 4 числа экспозиции в поплавке; Второй имеет 4 CMSampleBufferRef данные изображения; Последний имеет 4 UIImage * который конвертируется из второго для отображения на экране. Все, что мне нужно сделать, это либо сохранить UIImages с номером экспозиции в моем альбоме в формате jpeg, либо сохранить прямо из CMSampleBufferRefс моим номером времени выдержки для моего альбома как jpeg (я не знаю, думаю, что это возможно, хотя).


Мои выводы: так, из этого поста и этого официального документа я узнал, что на самом деле UIImage не содержит метаданных.

После долгих исследований я получил два удара, которые, казалось бы, были на правильном пути.

Один использует Photo Framework, чтобы установить экспозицию в качестве актива изображения и добавить его в альбом. Это и это, и многие другие посты помогли в кодировании. Тем не менее, я не смог найти какое-либо свойство, которое я мог бы установить экспозиции. Свойства "Чтение метаданных актива" в PHAsset, кажется, все, что я мог изменить, у которого нет времени экспозиции.

Другой - это ввод-вывод изображения -> CGImageProperties -> Ключи словаря EXIF ​​-> kCGImagePropertyExifExposureTime. Функция CGImageDestinationSetProperties может установить его. Но это для записи данных изображения в приложение вместо сохранения изображения в альбом... Итак, я наконец-то нашел свойство времени выдержки, но не могу его использовать...


Я что-то пропустил?? Поскольку это кажется очень легким делом, мой коллега по электротехнике посмотрел на меня, потому что я идиот, который провел целый день, не мог этого понять...


Обновление:

Это похоже на creationRequestForAssetFromImageAtFileURL: Метод сможет сохранить изображение с EXIF ​​в альбом. Этот пост ( метаданные потеряны при сохранении фотографии с использованием PHPhotoLibrary) указывает, что лучше временно сохранить данные изображения с информацией EXIF, а затем вызвать метод выше.

Я взял код из этого поста ( Сохранение фотографии с метаданными в Camera Roll с определенным именем файла) и изменил его.

создать альбом:

PHFetchResult *normalAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];

NSLog(@"There are %lu albums fetched.", (unsigned long)normalAlbums.count);//output 0 I don't know why

_album = normalAlbums.firstObject;// this give me nil, but still can save image to the album, is this the cause of the problem?

Получить информацию EXIF:

//imageSampleBufferArray is the type of CMSampleBufferRef that has the image    
CMSampleBufferRef sampleBuf = (CMSampleBufferRef)CFArrayGetValueAtIndex(imageSampleBufferArray, i);
NSDictionary* exifAttachments = (NSDictionary*)CMGetAttachment(sampleBuf, (CFStringRef)@"{Exif}", NULL);

Сохранить изображение:

+(void)saveImageWithMetaToCameraRoll:(UIImage*)image album:(PHAssetCollection *)album exif:(NSDictionary *)metadata{

    NSMutableDictionary *meta = [metadata mutableCopy];
    NSData *imageData = UIImageJPEGRepresentation(image, 1.0f);
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) imageData, NULL);

    NSString *timestamp = [NSString stringWithFormat:@"%.0f", [[NSDate date] timeIntervalSince1970] * 1000];
    NSString *fileName = [NSString stringWithFormat:@"IMG_%@.jpeg", timestamp];

    NSURL *tmpURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]];

    CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef) tmpURL, kUTTypeJPEG, 1, NULL);
    CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef) meta);

    CGImageDestinationFinalize(destination);
    CFRelease(source);
    CFRelease(destination);

    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        PHAssetChangeRequest *newAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:tmpURL];
        PHObjectPlaceholder *placeholderAsset = newAssetRequest.placeholderForCreatedAsset;

        if (album) {
            PHAssetCollectionChangeRequest *changeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album];

            [changeRequest addAssets:@[placeholderAsset]];
        }

    } completionHandler:^(BOOL success, NSError *error) {
        //Clean up the file:
        [[NSFileManager defaultManager] removeItemAtURL:tmpURL error:nil];

        if (error) {
            NSLog(@"%@", error);
        }

    }];
}

Однако, когда я смотрю на изображение в только что снятом альбоме, в нем по-прежнему нет информации EXIF, такой как время экспозиции. Все еще расследую это...

0 ответов

Другие вопросы по тегам