My app can take image from photo library. For the first time app open, it can take latest image.
But after I open app, go to background, open photo library and modify image, and come back to app, when user choose photo, it is not the latest image.
When I log image url in assets, it show the same one before and after modify image. Is it supposed to be same? Or different after image is modified?
Asset = ALAsset - Type:Photo,
URLs:assets-library://asset/asset.PNG?id=4E226E36-2D9C-449C-92AE-5036938603A9&ext=PNG
- (void) loadAssetsForGroup: (ALAssetsGroup*) group withCompletionHandler: (void (^)(NSArray*)) completionHandler {
__strong NSMutableArray* assets = [NSMutableArray array];
[group enumerateAssetsUsingBlock: ^(ALAsset* result, NSUInteger index, BOOL* stop) {
if (!result) {
completionHandler(assets);
return;
}
[assets addObject: result];
}];
}
Related
I'm developing app that works with video. It makes short movies from recorded or exported from camera roll videos. I need help with some unexpected behavior.
When I export video recorded with apple slow motion effect - such effect is lost in video in my app.
This's reproduced on iPhone 6 and 6+ and I assume on iPhone 5s too. On iPhone 5s/6/6+ Simulator, everything is ok. To export video I use iOS SDK ALAssetsLibrary API, code:
NSMutableArray* allVideos = [[NSMutableArray alloc] init];
self.assetLibrary = [[ALAssetsLibrary alloc] init];
[self.assetLibrary enumerateGroupsWithTypes: ALAssetsGroupAll
usingBlock: ^(ALAssetsGroup* group, BOOL* stop1){
if (group) {
[group setAssetsFilter: [ALAssetsFilter allVideos]];
[group enumerateAssetsUsingBlock: ^(ALAsset* asset, NSUInteger index, BOOL* stop2){
if (asset) {
[allVideos addObject: asset];
}
}];
}
else {
//sort by last shooted video
self.view.videoAssetRepresentations = [allVideos sortedArrayUsingComparator: ^NSComparisonResult (ALAsset* obj1, ALAsset* obj2) {
return [[obj1 valueForProperty: ALAssetPropertyDate] timeIntervalSince1970] < [[obj2 valueForProperty: ALAssetPropertyDate] timeIntervalSince1970];
}];
}
}
failureBlock: ^(NSError* error){
DbgLog(#"error enumerating AssetLibrary groups %#\n", error);
}];
To play exported video I use AVPlayer instance.
Please help me - how can I solve my problem?
PS - Instagram app can do this, tested on iPhone 6. Exported video contains slow motion effect inside Instagram app.
See: https://devforums.apple.com/message/1025773#1025773
It seems that you cannot do this with the ALAssetsLibrary. However, with the new Photos framework for iOS 8+ you can use PHAssetMediaSubtypeVideoHighFrameRate
I am creating an app that fetches photos and videos from the library.
I am using ALAssetsLibrary to fetch the contents from the library. But I can't retrieve the videos album from the library using this.
I am using the following code to retrieve the contents:
[library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
if (group || group.numberOfAssets >= 1)
{
[tmpAssets addObject:group];
}else{
self.assetAlbums = tmpAssets;
*stop = YES;
if(self.assetAlbums.count){
//parse contents and reload view
}
}
}
failureBlock:^(NSError *error)
{
//failed
}];
I am getting all other pictures and videos.
I have used a workaround of creating one videos album and filling its contents with the results from the ALAssetsLibraryGroupsEnumerationResultsBlock with allVideos filter.
but the ones that I upload from iTunes (those that get into the videos folder in the library) are not getting retrieved.
I need to know if an image is already in the iOS gallery. I am developing a messaging client app and, in my chat list, I am able to download images/videos of incoming messages when I tap into the image thumbnail.
The issue is, when I tap in the thumbnail, I download and save that image into the iOS photo gallery, but if I tap again I don't want to download and save it again, I want to retrieve it from the photo gallery.
Resuming, I want to look for the image in the photo gallery and retrieve it.
Here is my code to save the image in my custom photo album using ALAssetsLibrary:
[self writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)image.imageOrientation completionBlock:
^(NSURL* assetURL, NSError* error)
{
if (error!=nil) {
completionBlock(error);
return;
}
//add the asset to the custom photo album
[self addAssetURL: assetURL
toAlbum:albumName
withCompletionBlock:completionBlock];
}
];
-(void)addAssetURL:(NSURL*)assetURL toAlbum:(NSString*)albumName withCompletionBlock:(SaveImageCompletion)completionBlock
{
__block BOOL albumWasFound = NO;
[self enumerateGroupsWithTypes:ALAssetsGroupAlbum
usingBlock:
^(ALAssetsGroup *group, BOOL *stop)
{
if ([albumName compare: [group valueForProperty:ALAssetsGroupPropertyName]]==NSOrderedSame) {
albumWasFound = YES;
[self assetForURL: assetURL
resultBlock:
^(ALAsset *asset)
{
//add photo to the target album
[group addAsset: asset];
completionBlock(nil);
} failureBlock: completionBlock
];
return;
}
if (group==nil && albumWasFound==NO) {
//Target album does not exist, create it
__weak ALAssetsLibrary* weakSelf = self;
[self addAssetsGroupAlbumWithName:albumName
resultBlock:
^(ALAssetsGroup *group)
{
[weakSelf assetForURL: assetURL
resultBlock:
^(ALAsset *asset)
{
//add photo to the newly created album
[group addAsset: asset];
completionBlock(nil);
} failureBlock: completionBlock
];
} failureBlock: completionBlock
];
return;
}
} failureBlock: completionBlock
];
}
Maybe with the assetURL I could do it, but I have been searching in Apple's documentation and I didn't see anything.
Thanks!!
You can get Asset URL after the save process using completion block. You can retrieve the saved image using this Asset URL.
Unfortunately, you can't check file exist in Photolibrary. The reason behind is, the system will automatically embed many extra information with the image while you save in to Photolibrary. example like location, time etc.. So the binary content will be different for same images.
So, you have only one solution. Save the images into document directory and do a file exist using algorithms like CRC, MD5 etc..
I'm trying to get last picture from iphone camera roll. I use the following code:
UIImage* __block image = [[UIImage alloc] init];
ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup* group, BOOL* stop) {
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
if ([group numberOfAssets] > 0) {
[group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:[group numberOfAssets]-1] options:NSEnumerationConcurrent usingBlock:^(ALAsset* alAsset, NSUInteger index, BOOL* innerStop) {
if (alAsset) {
ALAssetRepresentation* rawImage = [alAsset defaultRepresentation];
image = [UIImage imageWithCGImage:[rawImage fullScreenImage]];
[self doTheJobWithImage:image];
// Inside doTheJobWithImage: a segue is also performed at the end
}
}];
}
} failureBlock:^(NSError* error) {
NSLog(#"Error: %#", [error localizedDescription]);
}];
It works but with flaws (I'm using Instruments and Zombies to debug it):
It seems to read every picture inside camera roll. So, first question: doesn't enumerateAssetsAtIndexes: only retrieve the specified images (atIndexes)? What's wrong with my code?
Adding to previous problem, memory becomes a problem when a lot of pictures are in camera roll. My app crashes if too many or, if it works, it seems retrieved images are NEVER deallocated, so the second or third time i call this code, it crashes anyway due to memory leaks. So second question: how do I force my code to deallocate everything after calling doTheJobWithImage: ?
I'm using xcode 4.6, ios 6 and ARC. Thanks in advance.
After few hours, I figured out that nothing is wrong with the code here. It is the right code to extract last picture in camera roll (if somebody ever needs it). The problem was inside doTheJobWithImage: , I solved it replacing
[self doTheJobWithImage:image];
and storing the resulting image somewhere else, and THEN performing doTheJobWithImage: after picture enumeration was done.. Saying this just in case somebody else is interested.
I have transfered an MP4 from iTunes to my iPad. If I open the Videos app I can see it listed - there's the thumbnail and the filename below (my_file.mp4). However the actual filename of the asset is changed in iOS to some unique value - IMG_001.MOV, for example. I would like to get the the original filename as it is listed in the Videos app (my_file.mp4). How are where do I find this?
Thanks
Here is a Code to get the Real name of AssetsFile
ALAssetsGroupEnumerationResultsBlock assetsEnumerationBlock = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result) {
[self.arrAssetsMedia addObject:result];
}
ALAssetRepresentation *rep = [result defaultRepresentation];
if (rep.filename!=nil) {
NSLog(#"File name is::%#",rep.filename);
[arrMediaFileName addObject:rep.filename];
}
};
Note:ALAssetRepresentation has a property - (NSString *)filename with the help of this we can get the file name
You Can't get the MP4 file from your device with its original name.
The only way to retrieve the PhotoGallery item (photos/videos) from your device to your application is through ALAssetLibrary.
The items will have names such as assets-library://asset/asset.MP4?id=1000000001&ext=MP4
So you can track the URL and get the MP4 using ALAsset Library.