Отображать изображение из URL, полученного из ALAsset в iPhone
Я использую ALAsset Framework для доступа к файлам в галерее устройств.
До сих пор я могу получить доступ к миниатюре и отобразить ее.
Я хочу отобразить фактическое изображение в представлении изображения, но я не могу понять, как это сделать.
Я попытался использовать поле URL в объекте ALAsset, но не увенчался успехом.
Кто-нибудь знает, как это можно сделать?
Вот некоторый код, где мне удалось получить доступ к миниатюре и поместить его в ячейку таблицы:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
//here 'asset' represents the ALAsset object
asset = [assets objectAtIndex:indexPath.row];
//i am accessing the thumbnail here
[cell.imageView setImage:[UIImage imageWithCGImage:[asset thumbnail]]];
[cell.textLabel setText:[NSString stringWithFormat:@"Photo %d", indexPath.row+1]];
return cell;
}
Ответы
Ответ 1
API немного изменил правила, и вы больше не получаете прямой доступ к файловой системе в библиотеку iPhoto. Вместо этого вы получаете URL-адрес библиотеки ресурсов.
assets-library://asset/asset.JPG?id=1000000003&ext=JPG
Вы используете объект ALAssetLibrary для доступа к объекту ALAsset через URL.
поэтому из документов для ALAssetLibrary запишите это в заголовок (или ваш источник)
typedef void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *asset);
typedef void (^ALAssetsLibraryAccessFailureBlock)(NSError *error);
который не является строго необходимым, но сохраняет вещи довольно.
а затем в вашем источнике.
-(void)findLargeImage
{
NSString *mediaurl = [self.node valueForKey:kVMMediaURL];
//
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation *rep = [myasset defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
if (iref) {
largeimage = [UIImage imageWithCGImage:iref];
[largeimage retain];
}
};
//
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror)
{
NSLog(@"booya, cant get image - %@",[myerror localizedDescription]);
};
if(mediaurl && [mediaurl length] && ![[mediaurl pathExtension] isEqualToString:AUDIO_EXTENSION])
{
[largeimage release];
NSURL *asseturl = [NSURL URLWithString:mediaurl];
ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
[assetslibrary assetForURL:asseturl
resultBlock:resultblock
failureBlock:failureblock];
}
}
Несколько вещей, чтобы отметить, что это использует блоки, которые были для меня новыми, прежде чем я начал перенос iOS4, но вы можете посмотреть
https://www.mikeash.com/pyblog/friday-qa-2008-12-26.html
и
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html
Они немного наклоняют голову, но если вы думаете о них как о селекторах уведомлений или обратных вызовах, это помогает.
Также
- когда
findLargeImage
возвращает
resultblock не будет запущен как его
обратный вызов. Настолько largeImage не будет
действительный еще.
-
largeImage
должен быть
переменная экземпляра, не привязанная к
Метод.
Я использую эту конструкцию для этого, используя этот метод, но вы можете найти что-то более подходящее для вашего использования.
[node.view findLargeImage];
UIImage *thumb = node.view.largeImage;
if (thumb) { blah blah }
То, что я узнал, пытаясь заставить эту работу в любом случае.
Обновление iOS 5
Когда срабатывает результирующий блок с iOS5 и, возможно, одноядерными устройствами, я не могу полагаться на изображение, доступное сразу после вызова findLargeImage
. Поэтому я изменил его, чтобы вызвать делегата.
@protocol HiresImageDelegate <NSObject>
@optional
-(void)hiresImageAvailable:(UIImage *)aimage;
@end
и comme cá
//
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation *rep = [myasset defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
if (iref) {
UIImage *largeimage = [UIImage imageWithCGImage:iref];
[delegate hiresImageAvailable:large];
}
};
Ответ 2
Уоррен ответил хорошо для меня. Одной из полезных вещей для некоторых людей является одновременное включение ориентации изображения и масштабных метаданных. Вы делаете это в своем блоке результатов следующим образом:
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation *rep = [myasset defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
if (iref)
{
UIImage *largeimage = [UIImage imageWithCGImage:iref scale:[rep scale] orientation:[rep orientation]];
[delegate hiresImageAvailable:large];
}
};
В этом случае вызов imageWIthCGImage
имеет масштаб и orientation
, добавленный при создании UIImage
для вас.
[UIImage imageWithCGImage:iref scale:[rep scale] orientation:[rep orientation]];
Один трюк, который следует отметить, заключается в том, что если вы используете [rep fullScreenImage]
вместо [rep fullResolutionImage]
на iOS 5, вы получаете изображение, которое уже повернуто - оно, однако, находится в разрешении экрана iPhone, то есть оно имеет более низкое разрешение.
Ответ 3
Просто, чтобы объединить ответы Уоррена и oknox в более короткий фрагмент:
ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
[assetsLibrary assetForURL:self.selectedPhotos[i] resultBlock: ^(ALAsset *asset){
ALAssetRepresentation *representation = [asset defaultRepresentation];
CGImageRef imageRef = [representation fullResolutionImage];
if (imageRef) {
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
imageView.image = [UIImage imageWithCGImage:imageRef scale:representation.scale orientation:representation.orientation];
// ...
}
} failureBlock: ^{
// Handle failure.
}];
Мне лично нравится устанавливать failureBlock
на nil
.
Ответ 4
NSURL* aURL = [NSURL URLWithString:@"URL here"];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library assetForURL:aURL resultBlock:^(ALAsset *asset)
{
UIImage *copyOfOriginalImage = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage] scale:0.5 orientation:UIImageOrientationUp];
cell.backgroundView = [[UIImageView alloc] initWithImage:copyOfOriginalImage];
}
failureBlock:^(NSError *error)
{
// error handling
NSLog(@"failure-----");
}];
просто предоставите UIReferenceURl, который вы получили для изображения в фотобиблиотеке, приведенной выше... его просто отлично работает.,. Я сделал это в
Изменить
cell.backgroundView = [[UIImageView alloc] initWithImage:copyOfOriginalImage];
Для
imageView.image = copyOfOriginalImage;