Как получить эскиз или путь для сохранения из UIImagePickerController для использования в UIImageView?

Может ли кто-нибудь объяснить или показать пример кода того, как я могу использовать эскиз, который будет помещен в UIImageView после того, как пользователь выберет фотографию с помощью UIImagePickerController?

Допустим, я хочу установить миниатюру в качестве изображения ячейки табличного представления. Когда пользователь нажимает на ячейку, отображается средство выбора изображения, и пользователь выбирает изображение, которое уже есть на его устройстве. Я также хочу сохранить путь к этой миниатюре, чтобы при следующем отображении представления можно было показать правильную миниатюру.

Я могу отобразить средство выбора изображения, и мой делегат получит выбранное изображение правильно, но мне нужен путь к миниатюре, и я хочу загрузить миниатюру, используя этот путь (т.е. я хочу сохранить путь). Я искал сегодня несколько часов и не понял этого. Возможно, я не понимаю ALAsset, а может, это что-то еще, но я не могу найти никаких примеров, которые бы мне помогли. Я никогда раньше не использовал средство выбора изображений или ALAsset, так что я совершенно новичок в этом.


person viperacr99    schedule 11.01.2011    source источник


Ответы (4)


// Если вы читаете это и смотрите на комментарии ниже и думаете ?? WTF ?? это потому, что я редактирую свой исходный ответ, а не отправляю два ответа в надежде, что все станет чище. Важно знать, что ALAssetsLibrary относится к iOS 4.x.

Приведенный ниже код будет работать, чтобы получить URL-адрес библиотеки ресурсов, а затем создать UIImage из представления эскиза. Хотя я использую URL-адрес библиотеки ресурсов напрямую, нет причин, по которым этот же код не может начинаться с преобразования строкового представления в NSURL, чтобы удовлетворить присваиванию imageURL. Отказ от ответственности: этот код, вероятно, протекает или что-то еще хуже, но он отвечает на вопрос исходного автора и, надеюсь, представляет ценность.

Приведенный ниже код сильно заимствован из вопроса о переполнении стека, который охватывает в основном ту же тему. В дополнение к приведенному здесь коду я включил AssetsLibrary.framework и определения типов ALAssetsLibrary, упомянутые в другом вопросе.

Весь фокус в том, что вы не можете напрямую ссылаться на NSURL из библиотеки ресурсов. Я думаю (хотя и не знаю), что он каким-то образом ссылается на хранилище данных, а не на файл, поэтому данные, возвращаемые с URL-адреса, не являются прямым NSData, поэтому вы не можете использовать его по-старому.

В коде есть UIImageView, который называется photo. Надеюсь, во всем остальном легко разобраться.

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenceURL];
    NSLog(@"%@",imageURL);
    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
    {
        CGImageRef iref = [myasset thumbnail];
        if (iref) {
            UIImage *theThumbnail = [UIImage imageWithCGImage:iref];
            [[self photo] setImage:theThumbnail];

        }
    };


    ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
    {
        NSLog(@"booya, cant get image - %@",[myerror localizedDescription]);
    };

    if(imageURL)
    {
        ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
        [assetslibrary assetForURL:imageURL 
                       resultBlock:resultblock
                      failureBlock:failureblock];
    }

    [self dismissModalViewControllerAnimated:YES];
}

Если вам не нужна миниатюра, но вы хотите получить полную фотографию, вы просто измените код в блоке AssetForURLResult на что-то вроде этого:

       ALAssetRepresentation *rep = [myasset defaultRepresentation];
    CGImageRef iref = [rep fullResolutionImage];

Мы можем оставить это упражнение для пользователя.

Удачи, надеюсь, это поможет вам прояснить ситуацию.

person Walter    schedule 12.01.2011
comment
Если пользователь удалит изображение из фотопленки, это не будет проблемой, изображение в моем представлении останется пустым. Картинка не является необходимостью для остальной части обзора. - person viperacr99; 12.01.2011
comment
Картинка не является необходимостью для остальной части обзора. Я ориентируюсь на IOS 4.0 и выше. Чтобы упростить задачу, скажем, я хочу поместить полноразмерное изображение в UIImageView. Как я могу это сделать, если у меня есть только объект NSURL из информационного словаря? То, что я пробовал до сих пор, не сработало, полагаю, я упускаю что-то очевидное. - person viperacr99; 12.01.2011
comment
Объект NSURL укажет на изображение, и вы сможете его скачать. Поскольку вы ориентируетесь на IOS 4.0, у вас есть возможность перейти в саму библиотеку активов. В блоге iCode есть руководство (icodeblog .com / 2010/07/08 / asset-libraries-and-blocks-in-ios-4), но, может быть, вы это уже видели? Когда у вас есть актив, вы можете использовать метод valueForPropery и получить ALAssetPropertyURLs, который представляет собой словарь, содержащий URL-адреса файлов. - person Walter; 12.01.2011
comment
Когда я получаю объект NSURL из результатов средства выбора изображений и наводю курсор на объект во время отладки, он печатается как что-то вроде assets-library: //asset/asset.JPG? Id = 10000000002 & ext = JPG. Если я создаю объект NSData с помощью dataWithContentsOfURL: selectedPictureNSURL, это не сработает. Я видел учебник, который вы связали, но я не понимаю, как использовать библиотеку активов, чтобы получить только одно изображение, и я не могу найти никаких примеров при поиске. Спасибо за помощь! - person viperacr99; 12.01.2011

Я уже в основном разобрался. Трудность, с которой я столкнулся, заключалась в понимании блоков, в основном синтаксис блоков затруднял понимание того, что они собой представляют и как они работают.

В делегате для UIImagePickerController, когда пользователь выбрал изображение, вы можете получить путь к изображению в библиотеке ресурсов, используя:

NSURL *path = [info objectForKey:UIImagePickerControllerReferenceURL];

С помощью этого объекта вы можете получить полноразмерное изображение или миниатюру, используя следующий код:

ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
    ALAssetRepresentation *rep = [myasset defaultRepresentation];
    CGImageRef iref = [rep fullResolutionImage];
    if (iref) {
        // Gets the full size image
        self.fullSizeImage = [UIImage imageWithCGImage:iref];
    }

    // Gets the thumbnail
    self.thumbnail = [UIImage imageWithCGImage:[myasset thumbnail]];
};

ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror)
{
    NSLog(@"in failureblock, got an error: %@",[myerror localizedDescription]);
};

ALAssetsLibrary *assetsLib = [[ALAssetsLibrary alloc] init];
[assetsLib assetForURL:urlForImage resultBlock:resultblock failureBlock:failureblock];

Эта страница действительно помогла мне понять Блоки: Блоки в iOS 4
См. также отображение изображения из URL, полученного из ALAsset в iPhone.

person viperacr99    schedule 12.01.2011

Сохранение URL-адреса может быть проблематичным:

  1. по крайней мере, в iOS 4.x уникальность URL-адресов не гарантируется. Их можно использовать повторно, если пользователь удаляет / добавляет изображения, что, очевидно, является обычным явлением. Таким образом, сохраненный URL-адрес может указывать на другую картину в будущем!
  2. Когда пользователь обновляется до iOS 5, URL-адреса становятся недействительными. ФУ!!! Apple переписала библиотеку фотографий без обратной совместимости.
person AfWiz    schedule 17.12.2011

Вы можете сохранить изображение, которое вы выбрали из imagePicker, в каталог документов, чтобы ссылаться на него из средства выбора. Вот код, который вы можете использовать для сохранения изображения. Реализуйте этот метод в методе обратного вызова, вызываемом, когда пользователь выбирает фотографию из средства выбора.

 NSFileManager   fileManager    = [NSFileManager defaultManager];

    NSArray*  output_PDF_paths  =  NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);

    NSString* output_PDF_documentsDirectory = [output_PDF_paths objectAtIndex:0];
    NSString* output_PDF_ABSOLUTE_PATH  = [output_PDF_documentsDirectory stringByAppendingPathComponent:@"ImageName.png"];  

    BOOL success_new = [UIImagePNGRepresentation(ProfilePhotoselected) writeToFile:previewPagePath atomically:YES];

// Здесь «ProfilePhotoselected» - это изображение, которое вы получаете из средства выбора в качестве аргумента в вашем методе callabck

person Snehal    schedule 12.01.2011
comment
Это один из способов сделать это, но проблема в том, что мне также придется реализовать код, который может удалять изображения из каталога документов, которые больше не используются, не говоря уже о том, что для этого просто потребуется больше места. В идеале я бы хотел, чтобы изображение сохранялось только в фотопленке, и если пользователь удалит изображение оттуда, ничего страшного, мой код просто не будет отображать изображение. - person viperacr99; 12.01.2011