I am using this code to save image into the album but images are being saved in Camera Roll album. I want to save images in WEAVE album. I'm using this code:
CGRect screenRect=CGRectMake(0, 0, viewPlay.frame.size.width, viewPlay.frame.size.height);
UIGraphicsBeginImageContext(screenRect.size);
CGContextRef ctx=UIGraphicsGetCurrentContext();
[[UIColor whiteColor] set];
CGContextFillRect(ctx, screenRect);
[self->viewPlay.layer renderInContext:ctx];
UIImage *screenImage=UIGraphicsGetImageFromCurrentImageContext();
UIImageWriteToSavedPhotosAlbum(screenImage, nil, nil, nil);
UIGraphicsEndImageContext();
this code is working fine for me. please give me any suggestion what change i do here to save image into WEAVE folder.
You can use the following code for doing this:
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library saveImage:image toAlbum:#"Midhun" withCompletionBlock:^(NSError *error) {
if (error!=nil)
{
NSLog(#"Error: %#", [error description]);
}
}];
Check this tutorial also: Custom Photo Album
For more info about ALAssetsLibrary
Related
I want to create and save a UIImage in iOS 10. I can create it either by taking a UIView snapshot or using UIGraphicsImageRenderer (shown below).
- (UIView *)createIcon
{
UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:CGSizeMake(200, 200)];
UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull context) {
[[UIColor darkGrayColor] setStroke];
[context strokeRect:renderer.format.bounds];
[[UIColor colorWithRed:158/255.0 green:215/255.0 blue:245/255.0 alpha:0.5] setFill];
[context fillRect:CGRectMake(30, 30, 140, 140)];
[[UIColor colorWithRed:243/255.0 green:122/255.0 blue:216/255.0 alpha:0.3] setFill];
CGContextFillEllipseInRect(context.CGContext, CGRectMake(30, 30, 120, 120));
}];
UIImageView *showImage = [[UIImageView alloc] initWithImage:image];
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
return showImage;
}
However, when I try to save using UIImageWriteToSavedPhotosAlbum by including the second last statement, Xcode goes into Debug with the following error report
(lldb) bt
* thread #5, queue = 'com.apple.root.default-qos', stop reason = signal SIGABRT
* frame #0: 0x00000001101611a6 libsystem_kernel.dylib`__abort_with_payload + 10
frame #1: 0x000000011015b86e libsystem_kernel.dylib`abort_with_payload_wrapper_internal + 89
frame #2: 0x000000011015b89b libsystem_kernel.dylib`abort_with_payload + 9
frame #3: 0x0000000108ab3af7 TCC`__CRASHING_DUE_TO_PRIVACY_VIOLATION__ + 182
frame #4: 0x0000000108ab3a41 TCC`__TCCAccessRequest_block_invoke.77 + 665
frame #5: 0x0000000108ab7273 TCC`__tccd_send_block_invoke + 274
So even though I didn’t use a camera to create the image, saving it to the photo album is a violation of privacy (hiss, boo)! I know it is possible to set up privacy keys in the plist but is there a more sensible alternative?
CLARIFICATION
I hope to use rendered images (or view snapshots) as assets in the app. So instead of is there a more sensible alternative ?
perhaps I should have asked
is there an alternative place to save images (i.e. as PNG or JPG files) so privacy is not an issue?
You can save any UIImage to the photo album but first you must ask the user for permission to do as this as it is indeed a privacy issue. If they don't give you access then you can't save the image at all.
The most sensible approach is to add the required privacy key to the info.plist.
This is the info.plist xml definition although it's easier to add the keys in the property list:
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Message requesting the ability to add to the photo library</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Message requestion the ability to access the photo library</string>
If you add these then when you first try to access or add to the photo library a popup will display with your message allowing the user to decide if they want your app to have access.
One good reason to put it in the info.plist file is that all the requests for access are then in a single easily visible place instead of somewhere random in your project.
EDIT
Here is how to save the image in documents which does not raise and privacy issues:
NSData *imageData = UIImagePNGRepresentation(image);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"image.png"]; //Add the file name
[imageData writeToFile:filePath atomically:YES]; //Write the file
If you want a jpg instead of a png use this instead:
NSData *imageData = UIImageJPEGRepresentation(image, 0.9); // Use whatever compression ratio you want instead of 0.9
Follow this code:
#import <Photos/Photos.h>
pragma mark - Save Image in photo album
- (void)addImageToCameraRoll:(UIImage *)image {
NSString *albumName = #"Your app name";
void (^saveBlock)(PHAssetCollection *assetCollection) = ^void(PHAssetCollection *assetCollection) {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
[assetCollectionChangeRequest addAssets:#[[assetChangeRequest placeholderForCreatedAsset]]];
} completionHandler:^(BOOL success, NSError *error) {
if (!success) {
NSLog(#"Error creating asset: %#", error);
}
}];
};
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:#"localizedTitle = %#", albumName];
PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:fetchOptions];
if (fetchResult.count > 0) {
saveBlock(fetchResult.firstObject);
} else {
__block PHObjectPlaceholder *albumPlaceholder;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCollectionChangeRequest *changeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:albumName];
albumPlaceholder = changeRequest.placeholderForCreatedAssetCollection;
} completionHandler:^(BOOL success, NSError *error) {
if (success) {
PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:#[albumPlaceholder.localIdentifier] options:nil];
if (fetchResult.count > 0) {
saveBlock(fetchResult.firstObject);
}
} else {
NSLog(#"Error creating album: %#", error);
}
}];
}
}
I do not know much about Objective-C.
I need to save the image in the gallery to custom name album and i used Canvas2ImagePlugin but image save to album camera roll.
Canvas2ImagePlugin using:
UIImage* image = [[[UIImage alloc] initWithData:imageData] autorelease];
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
How to use the name album in the function UIImageWriteToSavedPhotosAlbum? Or use another function?
Actually i don't know about phonegap. but i can give you hint that how we can achieved in ios. with help of ALAssetsLibrary, we can stored photo to custom album.
[self.library saveImage:image toAlbum:#"Touch Code Magazine" withCompletionBlock:^(NSError *error) {
if (error!=nil) {
NSLog(#"Big error: %#", [error description]);
}
}];
I want to use both of the objective c methods listed below in my application. The first method uploads a UIImagePicker photograph to a local server.
// I would still like to use this method structure but with the `AVCam` classes.
-(void)uploadPhoto {
//upload the image and the title to the web service
[[API sharedInstance] commandWithParams:[NSMutableDictionary dictionaryWithObjectsAndKeys:#"upload", #"command", UIImageJPEGRepresentation(photo.image,70), #"file", fldTitle.text, #"title", nil] onCompletion:^(NSDictionary *json) {
//completion
if (![json objectForKey:#"error"]) {
//success
[[[UIAlertView alloc]initWithTitle:#"Success!" message:#"Your photo is uploaded" delegate:nil cancelButtonTitle:#"Yay!" otherButtonTitles: nil] show];
} else {
//error, check for expired session and if so - authorize the user
NSString* errorMsg = [json objectForKey:#"error"];
[UIAlertView error:errorMsg];
if ([#"Authorization required" compare:errorMsg]==NSOrderedSame) {
[self performSegueWithIdentifier:#"ShowLogin" sender:nil];
}
}
}];
}
I want to add a second method : The second method performs an IBAction picture snap using AVCam but I changed it to void to launch the the view loads using [self snapStillImage].
EDIT
- (IBAction)snapStillImage:(id)sender
{
dispatch_async([self sessionQueue], ^{
// Update the orientation on the still image output video connection before capturing.
[[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] videoOrientation]];
// Flash set to Auto for Still Capture
[ViewController5 setFlashMode:AVCaptureFlashModeAuto forDevice:[[self videoDeviceInput] device]];
// Capture a still image.
[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (imageDataSampleBuffer)
{
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
[[[ALAssetsLibrary alloc] init] writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:nil];
//
photo = [[UIImage alloc] initWithData:imageData];
}
}];
});
}
Can someone please set photo via AVCam? At the very least humor me and start a dialogue about AVFoundation and its appropriate classes for tackling an issue like this.
Additional info: The avcam method is simply an excerpt from this https://developer.apple.com/library/ios/samplecode/AVCam/Introduction/Intro.html
#Aksh1t I want to set an UIImage named image with the original contents of the AVFoundation snap. Not UIImagePicker. Here is the method that sets the outlet using UIImagePicker.
#pragma mark - Image picker delegate methods
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// Resize the image from the camera
UIImage *scaledImage = [image resizedImageWithContentMode:UIViewContentModeScaleAspectFill bounds:CGSizeMake(photo.frame.size.width, photo.frame.size.height) interpolationQuality:kCGInterpolationHigh];
// Crop the image to a square (yikes, fancy!)
UIImage *croppedImage = [scaledImage croppedImage:CGRectMake((scaledImage.size.width -photo.frame.size.width)/2, (scaledImage.size.height -photo.frame.size.height)/2, photo.frame.size.width, photo.frame.size.height)];
// Show the photo on the screen
photo.image = croppedImage;
[picker dismissModalViewControllerAnimated:NO];
}
After that I simply want to upload it using the first method I posted. Sorry for being unclear. I basically want to do this in my new app (i was unclear about what app).
Take a photo using AVCam
Set that photo to an UIImageView IBOutlet named photo
Upload photo (the original AVCam photo) to the server
The basic framework is above and I will answer any questions
The following line of code in your snapStillImage method takes a photo into the imageData variable.
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
Next, you are creating one UIImage object from this data like this
UIImage *image = [[UIImage alloc] initWithData:imageData];
Instead of the above code, make a global variable UIImage *photo;, and initialize that with the imageData when your snapStillImage takes the photo like this
photo = [[UIImage alloc] initWithData:imageData];
Since photo is a global variable, you will then be able to use that in your uploadPhoto method and send it to your server.
Hope this helps, and if you have any question, leave it in the comments.
Edit:
Since you already have a IBOutlet UIImageView *photo; in your file, you don't even need a global variable to store the UIImage. You can just replace the following line in your snapStillImage method:
UIImage *image = [[UIImage alloc] initWithData:imageData];
with this line
photo.image = [[UIImage alloc] initWithData:imageData];
I downloaded an gif image from the network using AFNetworking 2.0 then save it to camera roll using ALAssetsLibrary
[assetsLibrary writeImageToSavedPhotosAlbum:[responseObject CGImage] orientation:(ALAssetOrientation)[responseObject imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error)
{
if (error)
{
[App showAlertWithTitle:#"Error" message:#"Save message failed"];
}
else
{
[App showAlertWithTitle:#"Success" message:#"Saved success"];
}
}];
Then I tried to retrieve this image from camera using UIImagePickerViewController, but the image I retrieved was not a GIF image but a jpeg image with reference url:
UIImagePickerControllerReferenceURL = "assets-library://asset/asset.JPG?id=2E7C87E4-5853-4946-B86B-CC8AAF094307&ext=JPG";
I don't know whether the fault is ALAssetsLibrary or UIImagePickerViewController and how to surpass it
The photo library does not support GIFs.
It has support for PHAssetMediaTypeImage (a JPG), PHAssetMediaTypeVideo (a MOV), or PHAssetMediaTypeAudio (probably an M4A, not sure here).
https://developer.apple.com/library/ios/documentation/Photos/Reference/Photos_Constants/index.html#//apple_ref/c/tdef/PHAssetMediaSubtype
The writeImageToSavedPhotosAlbum: methods only save still images as JPEGs, as do the new Photos methods. However, there are ways of saving other formats, including (yes!) GIF.
You don't need to mess about with CGImageRefs—just grab the GIF data and then save it, using the writeImageDataToSavedPhotosAlbum:metadata:completionBlock: method. Something like this:
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
NSData *data = [NSData dataWithContentsOfURL:
[NSURL URLWithString:#"http://somewhere/something.gif"]]];
[library writeImageDataToSavedPhotosAlbum:data
metadata:nil
completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
[App showAlertWithTitle:#"Error" message:#"Save message failed"];
} else {
[App showAlertWithTitle:#"Success" message:#"Saved success"];
}
}];
See this answer.
If you want to generate a GIF, it's somewhat more complex, but simply saving one is straightforward.
I'm developing and iOS app for iPad and I'm using a Repository called Grabkit in order to get images from different services like Instagram and Flicker in addition to images from the Camera Roll. The problem is that when the user selects a picture from the roll I get and URL such this: assets-library://asset/asset.JPG?id=DCFB9E49-93AA-49E3-89C8-2EE64AE2C4C6&ext=JPG
I've tried some codes to get the image from this kind of paths but no one has worked, such as the following:
ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
// Ask for the "Asset" for the URL. An asset is a representation of an image in the Photo application.
[library assetForURL:originalImage.URL
resultBlock:^(ALAsset *asset) {
// Here, we have the asset, let's retrieve the image from it
CGImageRef imgRef = [[asset defaultRepresentation] fullResolutionImage];
/* Instead of the full res image, you can ask for an image that fits the screen
CGImageRef imgRef = [[asset defaultRepresentation] fullScreenImage];
*/
// From the CGImage, let's build an UIImage
imatgetemporal = [UIImage imageWithCGImage:imgRef];
} failureBlock:^(NSError *error) {
// Something wrong happened.
}];
Is something in my code wrong? Must I try another code?