Problem:
I've got some trouble using writeImageDataToSavedPhotosAlbum:metadata:completionBlock: of AVAssetsLibrary
Question:
I want to use this over writeImageToSavedPhotosAlbum:metadata:completionBlock: to avoid possible compression of the photo library
Here is my code sample below :
CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(self.imageView.image.CGImage));
uint8_t *data = (uint8_t *)CFDataGetBytePtr(pixelData);
NSData *dataTOSave = [NSData dataWithBytesNoCopy:data length:CFDataGetLength(pixelData) freeWhenDone:NO];
ALAssetsLibrary *assetLib = [[ALAssetsLibrary alloc] init];
[assetLib writeImageDataToSavedPhotosAlbum:dataTOSave metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
NSLog(#"error %#", error);
}];
Error log in the completion block print null, but nothing appears in the photo library of my iPhone.
But now, if I used writeImageToSavedPhotosAlbum:metadata:completionBlock: it works great :
ALAssetsLibrary *assetLib = [[ALAssetsLibrary alloc] init];
[assetLib writeImageToSavedPhotosAlbum:[self.imageView.image CGImage] metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
NSLog(#"error %#", error);
}];
Error log still print null, and the image appears in the photo Library.
Note that I did this test with a small jpg image (250*333).
Does someone have any idea of why the first sample not working ? And why no errors is shown in the completion block ?
Related
I have developed a camera application with all basic functionalities. When you take a picture that image will be saved in the newly created folder but if I delete an image in my application its not getting deleted in that folder. I need to delete it permanently using objective C
You can't delete something from gallery, you can just use photos from gallery in your app and save to Gallery, but iOS doesn't give such permissions to other app as deleting something from Gallery.(if it is not jailbroken) There is no such functionality in WhatsApp too(or I can't see it).
FOR iOS 8.0+
You can only delete the ALAsset which is created by your app with document API [ALAsset setImageData:metadata:completionBlock:]
Saving Image photo.jpg to gallery by,
ALAssetsLibrary *lib = [ALAssetsLibrary new];
UIImage *image = [UIImage imageNamed:#"photo.jpg"];
[lib writeImageToSavedPhotosAlbum:image.CGImage metadata:#{} completionBlock:^(NSURL *assetURL, NSError *error) {
NSLog(#"Write image %# to asset library. (Error %#)", assetURL, error);
}];
You can Find this in "Saved Photos" album.
To delete:
ALAssetsLibrary *lib = [ALAssetsLibrary new];
[lib enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop) {
if(asset.isEditable) {
[asset setImageData:nil metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
NSLog(#"Asset url %# should be deleted. (Error %#)", assetURL, error);
}];
}
}];
} failureBlock:^(NSError *error) {
}];
ALAssetLibrary is Deprecated since iOS 9.0, you can use
PHPhotoLibrary Instead.
iOS 9.0+
// Delete asset from library
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetChangeRequest deleteAssets:assetArray];
} completionHandler:completionHandler];
In collection view didselect method i getting the url of selected image
UIImage *viewImage = _myma; // --- mine was made from drawing context
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Request to save the image to camera roll
[library writeImageToSavedPhotosAlbum:[viewImage CGImage] orientation:(ALAssetOrientation)[viewImage imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
NSLog(#"error");
} else {
NSLog(#"url %#", assetURL);
NSString *urlString = [assetURL absoluteString];
selectedurl = urlString;
//NSLog(#"myurl%#", selectedurl);
}
the in action button used to delete the selected images
NSURL *deleteurl = [NSURL URLWithString:selectedurl];
NSArray *arrDelete = [[NSArray alloc] initWithObjects:deleteurl , nil];
NSEnumerator *asset = [PHAsset fetchAssetsWithALAssetURLs:arrDelete options:nil];
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetChangeRequest deleteAssets:asset];// asset is an array
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"Finished Delete asset. %#", (success ? #"Success." : error));
if (success) {
NSLog(#"deleted");
}
}];
I want to saved an image in my photo albums, however I had succesfully saved the image but now I want to get the URL which would be my local URL that would open the image If I passes that to UIImage. I'm unable to get the saved image url as of error that "expression not allowed". How can I get the LOCAL URL of my saved image in iOS.
My Tried:
-(NSString *) imageSave: (UIImage *)image
{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)image.imageOrientation completionBlock:^(NSURL *assetURL, NSError *error )
{
[library assetForURL:assetURL resultBlock:^(ALAsset *asset )
{
self.temp1 = [NSString stringWithFormat:#"%#",assetURL];
NSLog(#"SAVED!");
}
failureBlock:^(NSError *error )
{
self.temp1 = [NSString stringWithFormat:#"NO"];
NSLog(#"Error Saving Image!!!");
}];
}];
return self.temp1;
}
I tried by ma making a property but that returns null.
Try following code that may help you.
UIImage *viewImage = YOUR UIIMAGE // ---
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Request to save the image to camera roll
[library writeImageToSavedPhotosAlbum:[viewImage CGImage] orientation:(ALAssetOrientation)[viewImage imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
NSLog(#"error");
} else {
NSLog(#"url %#", assetURL);
NSString *myString = [assetURL absoluteString];
}
}];
I would like to download the image from this URL http://placehold.it/200x200 and add into a specific album photo on iOS.
I spent hours to work with ALAssetsLibrary but unable to get it working properly... Here is my code :
// ViewController.h
#property (strong, atomic) ALAssetsLibrary* library;
// ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.library = [[ALAssetsLibrary alloc] init];
}
- (void)viewDidUnload {
self.library = nil;
[super viewDidUnload];
}
[...]
NSURL *image_url = [NSURL URLWithString:#"http://placehold.it/200x200"];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:image_url]];
void (^completion)(NSURL *, NSError *) = ^(NSURL *assetURL, NSError *error) {
if (error) NSLog(#"Error A : %#", [error description]);
};
void (^failure)(NSError *) = ^(NSError *error) {
if (error == nil) return;
NSLog(#"Error B : %#", [error description]);
};
[self.library saveImage:image toAlbum:#"Sample album" completion:completion failure:failure];
[...]
Output error are :
Connection to assetsd was interrupted or assetsd died
Error B : Error Domain=ALAssetsLibraryErrorDomain Code=-3300 "Write failed" UserInfo=0x7ff4da570ae0 {NSLocalizedFailureReason=There was a problem writing this asset because the write failed., NSLocalizedDescription=Write failed, NSUnderlyingError=0x7ff4da5709d0 "Write failed"}
There is multiple versions of ALAssetsLibrary online but I used the last one. There is a great tutorial about usage of ALAssetsLibrary but it's old (iOS5). Don't know if it's still supported correctly on iOS8. Can anyone help me to download an image and save it into a specific album please ? Thanks in advance.
This should work:
NSURL *image_url = [NSURL URLWithString:#"http://placehold.it/200x200"];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:image_url]];
[self.library writeImageToSavedPhotosAlbum:image.CGImage orientation:0 completionBlock:^(NSURL *assetURL, NSError *error) {}];
I'm saving a video to my PhotosAlbum, using this code:
ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];
[assetLibrary writeVideoAtPathToSavedPhotosAlbum:[NSURL URLWithString:videoPath] completionBlock:^(NSURL *assetURL, NSError *error)
{
NSError *removeError = nil;
[[NSFileManager defaultManager] removeItemAtURL:[NSURL URLWithString:videoPath] error:&removeError];
});
The video goes to the folder Videos but i want it to go to a specific folder with the name of the app. How can i accomplish this?
like this
ALAssetsLibrary* assetLibrary = [[ALAssetsLibrary alloc] init];
[assetLibrary writeVideoAtPathToSavedPhotosAlbum:[NSURL URLWithString:#""] completionBlock:^(NSURL *assetURL, NSError *error) {
[assetLibrary addAssetURL:[NSURL URLWithString:#""] toAlbum:#"" completion:^(NSURL *assetURL, NSError *error) {
NSError* removeError = nil;
[[NSFileManager defaultManager] removeItemAtURL:[NSURL URLWithString:#""] error:&removeError];
} failure:^(NSError *error) {
NSLog(#"%#", error);
}];
}];
I capture still image and save to camera roll with AV Foundation like this:
- (void) captureStillImage
{
AVCaptureConnection *stillImageConnection =
[self.stillImageOutput.connections objectAtIndex:0];
if ([stillImageConnection isVideoOrientationSupported])
[stillImageConnection setVideoOrientation:AVCaptureVideoOrientationPortrait];
[self.stillImageOutput
captureStillImageAsynchronouslyFromConnection:stillImageConnection
completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error)
{
if (imageDataSampleBuffer != NULL)
{
NSData *imageData = [AVCaptureStillImageOutput
jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
UIImage *image = [[UIImage alloc] initWithData:imageData];
[library writeImageToSavedPhotosAlbum:[image CGImage]
orientation:(ALAssetOrientation)[image imageOrientation]
completionBlock:^(NSURL *assetURL, NSError *error){
}];
}
else
{
NSLog(#"Error capturing still image: %#", error);
}
}
];
}
These images from my App when check again in Photos App don't have info about city name.
How to capture still image and save with its location name which can be display in photos app?
Thanks for help!
From the Docs : captureStillImageAsynchronouslyFromConnection
handler
A block to invoke after the image has been captured. The block
parameters are as follows: imageDataSampleBuffer The data that was
captured. The buffer attachments may contain metadata appropriate to
the image data format. For example, a buffer containing JPEG data may
carry a kCGImagePropertyExifDictionary as an attachment. See
ImageIO/CGImageProperties.h for a list of keys and value types.
So using that you can get the meta data.
CFDictionaryRef metaDict = CMCopyDictionaryOfAttachments(NULL, imageDataSampleBuffer, kCMAttachmentMode_ShouldPropagate);
CFMutableDictionaryRef mutable = CFDictionaryCreateMutableCopy(NULL, 0, metaDict);
NSDictionary *metaDict = [NSDictionary
dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat:self.currentLocation.coordinate.latitude], kCGImagePropertyGPSLatitude,
#"N", kCGImagePropertyGPSLatitudeRef,
[NSNumber numberWithFloat:self.currentLocation.coordinate.longitude], kCGImagePropertyGPSLongitude,
#"E", kCGImagePropertyGPSLongitudeRef,
#"04:30:51.71", kCGImagePropertyGPSTimeStamp,
nil];
NSLog(#"%#",metaDict);
CFDictionarySetValue(mutable, kCGImagePropertyGPSDictionary, (__bridge const void *)(metaDict));
and when saving to Asset Library use this method to add the meta data
[library writeImageToSavedPhotosAlbum:[image CGImage] metadata:mutable completionBlock: nil];