Pobierz ostatni obraz ze zdjęć.aplikacja?
Widziałem inne aplikacje to zrobić, gdzie można zaimportować ostatnie zdjęcie z aplikacji zdjęcia do szybkiego użycia, ale o ile wiem, Wiem tylko, jak uzyskać obraz, a nie ostatni (najnowszy). Czy ktoś może mi pokazać jak zdobyć ostatni obrazek?
13 answers
Ten fragment kodu pobierze najnowszy obraz z rolki aparatu (iOS 7 i poniżej):
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
// Within the group enumeration block, filter to enumerate just photos.
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
// Chooses the photo at the last index
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {
// The end of the enumeration is signaled by asset == nil.
if (alAsset) {
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
UIImage *latestPhoto = [UIImage imageWithCGImage:[representation fullScreenImage]];
// Stop the enumerations
*stop = YES; *innerStop = YES;
// Do something interesting with the AV asset.
[self sendTweet:latestPhoto];
}
}];
} failureBlock: ^(NSError *error) {
// Typically you should handle an error more gracefully than this.
NSLog(@"No groups");
}];
IOS 8 i wyżej:
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
PHAsset *lastAsset = [fetchResult lastObject];
[[PHImageManager defaultManager] requestImageForAsset:lastAsset
targetSize:self.photoLibraryButton.bounds.size
contentMode:PHImageContentModeAspectFill
options:PHImageRequestOptionsVersionCurrent
resultHandler:^(UIImage *result, NSDictionary *info) {
dispatch_async(dispatch_get_main_queue(), ^{
[[self photoLibraryButton] setImage:result forState:UIControlStateNormal];
});
}];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-13 02:28:35
[3]} świetna odpowiedź od iBrad, zadziałała prawie idealnie dla mnie. Wyjątkiem jest to, że zwracano obrazy w ich pierwotnej orientacji (np. do góry nogami, -90°, itp.).
Aby to naprawić po prostu zmieniłem fullResolutionImage
na fullScreenImage
.
Tutaj:
UIImage *latestPhoto = [UIImage imageWithCGImage:[representation fullScreenImage]];
Teraz działa smakowicie.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-17 16:20:08
Przykład Ibrada zawiera fragment iOS8, który najwyraźniej działa, ale znalazłem się zdezorientowany przez typ powrotu, który opisał. Oto fragment, który chwyta ostatni obraz, w tym opcje dotyczące wersji i wymagań dotyczących rozmiaru.
Na uwagę zasługuje możliwość żądania określonej wersji (oryginalnej, Aktualnej) i rozmiaru. W moim przypadku, ponieważ chcę zastosować zwrócony obraz do przycisku, żądam jego rozmiaru i przeskalowania, aby pasował do przycisku, do którego go aplikuję:
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
PHAsset *lastAsset = [fetchResult lastObject];
[[PHImageManager defaultManager] requestImageForAsset:lastAsset
targetSize:self.photoLibraryButton.bounds.size
contentMode:PHImageContentModeAspectFill
options:PHImageRequestOptionsVersionCurrent
resultHandler:^(UIImage *result, NSDictionary *info) {
dispatch_async(dispatch_get_main_queue(), ^{
[[self photoLibraryButton] setImage:result forState:UIControlStateNormal];
});
}];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-12 17:04:03
Dzięki za odpowiedź iBrad Apps.
Chciałem tylko zwrócić uwagę na zapobieganie błędom w specjalnym przypadku, gdy użytkownik nie ma zdjęć na swojej rolce zdjęć (dziwny przypadek, który znam):
// Within the group enumeration block, filter to enumerate just photos.
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
//Check that the group has more than one picture
if ([group numberOfAssets] > 0) {
// Chooses the photo at the last index
[group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:([group numberOfAssets] - 1)] options:0 usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {
// The end of the enumeration is signaled by asset == nil.
if (alAsset) {
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
UIImage *latestPhoto = [UIImage imageWithCGImage:[representation fullScreenImage]];
[self.libraryButton setImage:latestPhoto forState:UIControlStateNormal];
}
}];
}
else {
//Handle this special case
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-25 14:29:26
Zobacz odpowiedź Liama. fullScreenImage
zwróci skalowany obraz dopasowany do rozmiaru ekranu urządzenia. Aby uzyskać rzeczywisty rozmiar obrazu:
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
ALAssetOrientation orientation = [representation orientation];
UIImage *latestPhoto = [UIImage imageWithCGImage:[representation fullResolutionImage] scale:[representation scale] orientation:(UIImageOrientation)orientation];
Cytując Alassetrepresentation Class Reference na fullResolutionImage
:
Aby utworzyć prawidłowo obrócony obiekt UIImage z CGImage, należy użyć imageWithCGImage: scale: orientation: or initwithcgimage: scale: orientation:, przekazywanie wartości orientacji i skali.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-13 08:50:01
Oto rozwiązanie jak załadować ostatnie zdjęcie z galerii za pomocą Swift 3 :
func loadLastImageThumb(completion: @escaping (UIImage) -> ()) {
let imgManager = PHImageManager.default()
let fetchOptions = PHFetchOptions()
fetchOptions.fetchLimit = 1
fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending: true)]
let fetchResult = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: fetchOptions)
if let last = fetchResult.lastObject {
let scale = UIScreen.main.scale
let size = CGSize(width: 100 * scale, height: 100 * scale)
let options = PHImageRequestOptions()
imgManager.requestImage(for: last, targetSize: size, contentMode: PHImageContentMode.aspectFill, options: options, resultHandler: { (image, _) in
if let image = image {
completion(image)
}
})
}
}
Jeśli potrzebujesz większej prędkości, Możesz również użyć PHImageRequestOptions
i ustawić te:
options.deliveryMode = .fastFormat
options.resizeMode = .fast
I w ten sposób dostajesz to w swoim viewcontrolle (powinieneś zastąpić GalleryManager.Kierownik z klasą):
GalleryManager.manager.loadLastImageThumb { [weak self] (image) in
DispatchQueue.main.async {
self?.galleryButton.setImage(image, for: .normal)
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-02 14:12:15
Znalazłem literówkę, do której wstydzę się przyznać dłużej, niż powinna. Może zaoszczędzi to komuś innemu trochę czasu.
Tej linii brakowało dwukropka po indexSetWithIndex
:
[group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:[group numberOfAssets] - 1]options:0 usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-08 18:24:01
Oto wersja w Swift , która żąda danych i konwertuje je do interfejsu użytkownika, ponieważ dostarczona wersja zwraca pusty interfejs za każdym razem
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
let fetchResult = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: fetchOptions)
if let lastAsset: PHAsset = fetchResult.lastObject as? PHAsset {
let manager = PHImageManager.defaultManager()
let imageRequestOptions = PHImageRequestOptions()
manager.requestImageDataForAsset(lastAsset, options: imageRequestOptions) {
(let imageData: NSData?, let dataUTI: String?,
let orientation: UIImageOrientation,
let info: [NSObject : AnyObject]?) -> Void in
if let imageDataUnwrapped = imageData, lastImageRetrieved = UIImage(data: imageDataUnwrapped) {
// do stuff with image
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-10 01:00:55
Na podstawie odpowiedzi ibrada, oto szybka i brudna wersja Swift, która działa dla mnie w iOS 8.1:
let imgManager = PHImageManager.defaultManager()
var fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending: true)]
if let fetchResult = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: fetchOptions) {
imgManager.requestImageForAsset(fetchResult.lastObject as PHAsset, targetSize: self.destinationImageView.frame.size, contentMode: PHImageContentMode.AspectFill, options: nil, resultHandler: { (image, _) in
self.destinationImageView.image = image
})
}
Uwaga: to wymaga systemu iOS 8.0+. Pamiętaj, aby połączyć Framework Zdjęcia i dodać "Importuj zdjęcia" do pliku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-03 19:32:29
Oto połączenie odpowiedzi iBrad & Javiera (co działało świetnie), ale dostaję miniaturkę zamiast obrazu w pełnej rozdzielczości. Innym może się to przydać.
- (void)setCameraRollImage {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
if ([group numberOfAssets] > 0) {
// Chooses the photo at the last index
[group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:([group numberOfAssets] - 1)] options:0 usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {
// The end of the enumeration is signaled by asset == nil.
if (alAsset) {
UIImage *latestPhoto = [UIImage imageWithCGImage:[alAsset thumbnail]];
[self.cameraRollButton setImage:latestPhoto forState:UIControlStateNormal];
}
}];
}
} failureBlock: ^(NSError *error) {
}];
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-20 14:18:49
Xamarin.wersja IOS zaakceptowana odpowiedź (jak uzyskać ostatni obrazek) w tym wszystkie ogłoszenia z innych odpowiedzi:
private void ChooseLastTakenPictureImplementation()
{
var library = new ALAssetsLibrary();
// Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.
library.Enumerate(ALAssetsGroupType.SavedPhotos, (ALAssetsGroup assetsGroup, ref bool stop) =>
{
if (stop || assetsGroup == null)
{
return;
}
//Xamarin does not support ref parameters in nested lamba expressions
var lambdaStop = false;
//Check that the group has more than one picture
if (assetsGroup.Count > 0)
{
// Within the group enumeration block, filter to enumerate just photos.
assetsGroup.SetAssetsFilter(ALAssetsFilter.AllPhotos);
// Chooses the photo at the last index
assetsGroup.Enumerate(NSEnumerationOptions.Reverse, (ALAsset result, int index, ref bool innerStop) =>
{
// The end of the enumeration is signaled by asset == nil.
if (result != null)
{
var representation = result.DefaultRepresentation;
var latestPhoto = new UIImage(representation.GetImage(), representation.Scale, (UIImageOrientation)representation.Orientation);
// Stop the enumerations
lambdaStop = innerStop = true;
// Do something interesting with the AV asset.
HandleImageAutoPick(latestPhoto);
}
});
stop = lambdaStop;
return;
}
else
{
//Handle this special case where user has no pictures
}
}, error =>
{
// Typically you should handle an error more gracefully than this.
Debug.WriteLine(error.Description);
});
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:23
Jest to bardzo fajne podejście, ale jednym z problemów jest to, że musisz być w stanie utworzyć instancję PHPhotoLibrary i innych klas PHPhoto w czasie wykonywania, ponieważ w przeciwnym razie będą błędy łącza na iOS 7.X. X chciałem tylko to zaznaczyć, bo mam teraz problemy.
Uważam również, że musisz słabe łącze w ramach zdjęć, aby aplikacja działała na obu urządzeniach z iOS 8.X. X i iOS 7.Zainstalowane X. X (chociaż nie testowałem tego jeszcze.)
Jednym z problemów, na które napotykam, jest to, jak utworzyć instancję PHPhotoLibrary w czasie wykonywania. Czy ktoś ma na to fragmenty kodu?
Właściwie dla aplikacji, nad którą pracowałem, musiałem w końcu napisać kod uruchomieniowy do tworzenia instancji klasy PHPhotoLibrary i wywoływania metod frameworku zdjęć, aby aplikacja działała zarówno na iOS 7.x. x i iOS 8.x. X. ktoś inny może napotkać te same problemy, więc podałem kod poniżej - >
// PHPhotoLibrary_class will only be non-nil on iOS 8.x.x
Class PHPhotoLibrary_class = NSClassFromString(@"PHPhotoLibrary");
if (PHPhotoLibrary_class) {
/**
*
iOS 8..x. . code that has to be called dynamically at runtime and will not link on iOS 7.x.x ...
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title];
} completionHandler:^(BOOL success, NSError *error) {
if (!success) {
NSLog(@"Error creating album: %@", error);
}
}];
*/
// dynamic runtime code for code chunk listed above
id sharedPhotoLibrary = [PHPhotoLibrary_class performSelector:NSSelectorFromString(@"sharedPhotoLibrary")];
SEL performChanges = NSSelectorFromString(@"performChanges:completionHandler:");
NSMethodSignature *methodSig = [sharedPhotoLibrary methodSignatureForSelector:performChanges];
NSInvocation* inv = [NSInvocation invocationWithMethodSignature:methodSig];
[inv setTarget:sharedPhotoLibrary];
[inv setSelector:performChanges];
void(^firstBlock)() = ^void() {
Class PHAssetCollectionChangeRequest_class = NSClassFromString(@"PHAssetCollectionChangeRequest");
SEL creationRequestForAssetCollectionWithTitle = NSSelectorFromString(@"creationRequestForAssetCollectionWithTitle:");
[PHAssetCollectionChangeRequest_class performSelector:creationRequestForAssetCollectionWithTitle withObject:albumName];
};
void (^secondBlock)(BOOL success, NSError *error) = ^void(BOOL success, NSError *error) {
if (success) {
[assetsLib enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group) {
NSString *name = [group valueForProperty:ALAssetsGroupPropertyName];
if ([albumName isEqualToString:name]) {
groupFound = true;
handler(group, nil);
}
}
} failureBlock:^(NSError *error) {
handler(nil, error);
}];
}
if (error) {
NSLog(@"Error creating album: %@", error);
handler(nil, error);
}
};
// Set the first and second blocks.
[inv setArgument:&firstBlock atIndex:2];
[inv setArgument:&secondBlock atIndex:3];
[inv invoke];
}
else {
// code that always creates an album on iOS 7.x.x but fails
// in certain situations such as if album has been deleted
// previously on iOS 8...x. .
[assetsLib addAssetsGroupAlbumWithName:albumName
resultBlock:^(ALAssetsGroup *group) {
handler(group, nil);
} failureBlock:^(NSError *error) {
NSLog( @"Failed to create album: %@", albumName);
handler(nil, error);
}];
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-08 18:05:19
Poniższy kod działa z iOS7 i iOS8. Sprawdza również, czy w filtrze znajduje się obraz. Przed wykonaniem kodu należy sprawdzić uprawnienia albumu:
// get the latest image from the album
-(void)getLatestPhoto
{
NSLog(@"MMM TGCameraViewController - getLatestPhoto");
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
// Within the group enumeration block, filter to enumerate just photos.
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
// For this example, we're only interested in the last item [group numberOfAssets]-1 = last.
if ([group numberOfAssets] > 0) {
[group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:[group numberOfAssets]-1]
options:0
usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {
// The end of the enumeration is signaled by asset == nil.
if (alAsset) {
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
// Do something interesting with the AV asset.
UIImage *img = [UIImage imageWithCGImage:[representation fullScreenImage]];
// use the photo here ...
// we only need the first (most recent) photo -- stop the enumeration
*innerStop = YES;
}
}];
}
}
failureBlock: ^(NSError *error) {
// Typically you should handle an error more gracefully than this.
NSLog(@"No groups");
}];
}
(Ten kod jest zmodyfikowaną wersją z tutaj .)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-02 22:01:50