Как да получа миниатюра или път за запазване от UIImagePickerController, който да използвам за UIImageView?

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

Да кажем, че искам да задам миниатюра като изображение на клетка за изглед на таблица. Когато потребителят натисне клетката, се показва инструментът за избор на изображение и потребителят избира изображение, което вече е на устройството му. Също така искам да запазя пътя до това миниизображение, така че следващия път, когато се покаже изгледът, да може да се покаже правилното миниизображение.

Мога да покажа инструмент за избор на изображение и моят делегат получава избраното изображение правилно, но искам пътя до миниатюрата и искам да заредя миниатюрата, използвайки тази пътека (т.е. искам да запазя пътя). Днес търсих с часове и не разбрах това. Може би не разбирам ALAsset или може би е нещо друго, но не мога да намеря примери, които да ми помогнат. Никога досега не съм използвал инструмента за избор на изображения или ALAsset, така че съм напълно нов в това.


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


Отговори (4)


//Ако четете това и погледнете коментарите по-долу и си помислете ??WTF?? това е така, защото редактирам оригиналния си отговор, вместо да публикувам два отговора с надеждата, че нещата ще бъдат по-чисти. Важно е да знаете, че ALAssetsLibrary е нещо за iOS 4.x.

Кодът по-долу ще функционира, за да вземе URL адрес на библиотека с активи и след това да направи UIImage от миниатюрното представяне. Въпреки че използвам директно URL адреса на библиотеката с активи, няма причина същият този код да не може да започне с трансформиране на представяне на низ в NSURL, за да удовлетвори заданието imageURL. Отказ от отговорност: този код вероятно изтича или нещо по-лошо, но отговаря на въпроса на оригиналния автор и се надяваме, че е полезен.

Кодът по-долу е заимстван до голяма степен оттози въпрос за Stack Overflow, който обхваща основно същата тема. В допълнение към кода тук, включих AssetsLibrary.framework и ALAssetsLibrary typedefs, посочени в другия въпрос.

Целият трик е, че не можете да препращате към 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 от резултатите от инструмента за избор на изображение и задържа курсора на мишката върху обекта, докато отстранявам грешки, той се отпечатва като нещо като активи-библиотека://asset/asset.JPG?id=10000000002&ext=JPG. Ако създам NSData обект с помощта на dataWithContentsOfURL:chosenPictureNSURL, той се проваля. Видях урока, който сте свързали, но не разбирам как да използваме библиотеката с активи, за да получим само една снимка, нито мога да намеря примери при търсене. Благодаря за помощта досега! - 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 пренаписа Photo Library, без обратна съвместимост.
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