iPhone capture image crashes app when saving to Photos Album - iphone

In my app i make a screen capture:
UIImage *viewImage = [UIImage imageWithCGImage:UIGetScreenImage()];
CGRect cropRect = CGRectMake(0, 0, 320, 440);
CGImageRef imageRef = CGImageCreateWithImageInRect([viewImage CGImage], cropRect);
viewImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
captureImage = [[UIImage alloc] init];
captureImage = viewImage;
Then i want to save it to photos album:
UIImageWriteToSavedPhotosAlbum(anImage, self, #selector(savedPhotoImage:didFinishSavingWithError:contextInfo:), nil);
- (void) savedPhotoImage:(UIImage *)image
didFinishSavingWithError:(NSError *)error
contextInfo:(void *)contextInfo
{
NSString *themessage = #"This image has been saved to your Photos album. Tap to continue.";
NSString *errorTitle = #"Image saved.";
if (error) {
themessage = [error localizedDescription];
errorTitle = #"error";
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:errorTitle
message:themessage
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
The app crashes when saving to photos album.
The captured image is ok, i can successfully upload and display it.
I also tried loading an image from memory and saving it to Photos Album and it also worked.
I guess that i'm doing something wrong when i'm processing my image..
Any ideas?
Thanks!

As this question is too old I would like to show more modern way to do what you wanted.
This code can be used to capture the screen:
- (UIImage *) getScreenShot
{
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
CGRect rect = [keyWindow bounds];
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[keyWindow.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
And this code to save the image:
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^
{
PHAssetChangeRequest *changeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:screenShot];
}
completionHandler:^(BOOL success, NSError *error)
{
if (success)
{
NSLog(#"successfully saved");
}
else
{
NSLog(#"error saving to photos: %#", error);
}
}];}

Can you check the permission ? if its disabled, there is no alert will display next time.

Related

image getting saved in simulator gallery but not in iphone gallery

Trying to save the image in iphone gallery with following code below, but working fine in simulator, not in iphone.
-(void)saveTkt
{
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
CGRect rect = [keyWindow bounds];
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[keyWindow.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData * data = UIImagePNGRepresentation(img);
[data writeToFile:#"f.png" atomically:YES];
UIImageWriteToSavedPhotosAlbum(img, self, #selector(thisImage:hasBeenSavedInPhotoAlbumWithError:usingContextInfo:), nil);
}
edited code
-(void)saveTkt
{
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
CGRect rect = [keyWindow bounds];
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[keyWindow.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData * data = UIImagePNGRepresentation(img);
[data writeToFile:#"f.png" atomically:YES];
ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];
if (status != ALAuthorizationStatusAuthorized) {
//show alert for asking the user to give permission
}
//UIImageWriteToSavedPhotosAlbum(img, self, #selector(thisImage:hasBeenSavedInPhotoAlbumWithError:usingContextInfo:), nil);
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:[img CGImage] orientation:(ALAssetOrientation)[img imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
// TODO: error handling
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"error" message:[error localizedDescription] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
} else {
// TODO: success handling
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"alert" message:#"Saved suceesfully in photos album." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}];
ALAssetsLibraryGroupsEnumerationResultsBlock assetGroupEnumerator =
^(ALAssetsGroup *assetGroup, BOOL *stop) {
if (assetGroup != nil) {
// do somthing
}
};
ALAssetsLibraryAccessFailureBlock assetFailureBlock = ^(NSError *error) {
NSLog(#"Error enumerating photos: %#",[error description]);
};
NSUInteger groupTypes = ALAssetsGroupAll;
[library enumerateGroupsWithTypes:groupTypes usingBlock:assetGroupEnumerator failureBlock:assetFailureBlock];
}
Add Framework assetsLibrary
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
// TODO: error handling
} else {
// TODO: success handling
}
}];
[library release];
Apple's documentation say that the completion handler must conform to this:
- (void) image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo;
And there's an error parameter passed along, which you should print out to see what the actual true error is.
For example:
- (void) image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo
{
if(error != NULL)
{
NSLog( #"error while saving image is %#", [error localizedDescription]);
}
}
I think you should try with NSData first if you need It, or you can simply do that without NSData
NSData *dataImage = UIImageJPEGRepresentation(file,1);
UIImageView *img;
img.image = [[UIImage alloc] initWithData:dataImage];
UIImageWriteToSavedPhotosAlbum( [[UIImage alloc] initWithData:dataImage], nil, nil, nil);
Hope ,it will work

Fgallery save image to iPhone

Hi Sorry for being a noob but I'm learning. I have Fgallery working in my app but now I want to connect a bar button to an action to save the image to the phone. I need some code that gives me the current image (in the large image view) I hope someone can help me out with this. This is what I have:
- (void)handleEditCaptionButtonTouch:(id)sender {
// here we could implement some code to change the caption for a stored image
[networkGallery saveImageAtIndex:[networkGallery currentIndex]];
}
And here I have an image hard-coded but I need the current image:
- (void)saveImageAtIndex:(NSUInteger)index
{
UIImage *image = [UIImage imageNamed:#"background.png"];
if(image != nil){
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
}
return;
}
//saveImage method
-(void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
[BT_debugger showIt:self:[NSString stringWithFormat:#"finished saving image: %#", #""]];
NSString *message;
NSString *title;
if (!error) {
title = NSLocalizedString(#"SaveSuccessTitle", #"");
message = NSLocalizedString(#"SaveSuccessMessage", #"");
} else {
title = NSLocalizedString(#"SaveFailedTitle", #"");
message = [error description];
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:NSLocalizedString(#"ButtonOK", #"")
otherButtonTitles:nil];
[alert show];
[alert release];
}
Any help would be very appreciated.
Thanks in advance
DK
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
img.image = [info valueForKey:#"UIImagePickerControllerOriginalImage"];
[self dismissModalViewControllerAnimated:YES];
}
If someone else is looking for an answer. Here it is:
FGalleryPhoto *photo = [_photoLoaders objectForKey:[NSString stringWithFormat:#"%i", index]];
UIImage *saveImage = [photo fullsize];
In code above, in the stringWithFormat method, replace index with _currentIndex
FGalleryPhoto *photo = [_photoLoaders objectForKey:[NSString stringWithFormat:#"%i", _currentIndex]];
UIImage *saveImage = [photo fullsize];

SDWebImage corrupt images

I'm using SDWebImage (2.7.3 framework) and I receive corrupt images, I can't understand exactly the problem. If is the code (memory...)
(notes:
I get the same error using the SDWebImage project instead of the framework.
I'm implementing "autorelease" and other kinds of memory management.
This problem arises on devices (iPad), but not in the simulator)
__block CALayer *layerCover = [[CALayer alloc] init];
layerCover.frame = CGRectMake(3, 3, COVER_WIDTH_IPAD_SMALL, COVER_HEIGHT_IPAD_SMALL);
[btn.layer addSublayer:layerCover];
[_scroll addSubview:btn];
[btn release];
//request or load Vods Images
[[SDWebImageManager sharedManager] downloadWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#M", vod.cover]]
delegate:self options:SDWebImageProgressiveDownload success:^(UIImage *image, BOOL cached) {
if (image) {
layerCover.contents = (id)image.CGImage;
}
[layerCover release];
} failure:^(NSError *error) {
[layerCover release];
}];
//another kind
UIImage * imageTv = [UIImage imageNamed:#"bgDefaultTvImage.png"];
UIImageView * bgTvImage = [[UIImageView alloc] initWithFrame:CGRectMake(startX, 20, imageTv.size.width, imageTv.size.height)];
[bgTvImage setImage:imageTv];
CGFloat sizeWithIcon = imageTv.size.width;
CGFloat sizeHeightIcon = imageTv.size.height;
__block UIImageView * bgImageicon = [[UIImageView alloc] initWithFrame:CGRectMake((bgTvImage.frame.size.width-sizeWithIcon)/2,
(bgTvImage.frame.size.height-sizeHeightIcon)/2,
sizeWithIcon,
sizeHeightIcon)];
bgImageicon.contentMode = UIViewContentModeScaleAspectFit;
[bgTvImage addSubview:bgImageicon];
[tvTopView addSubview:bgTvImage];
/*
* Request ProgramImage
*/
[[SDWebImageManager sharedManager] downloadWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#&width=300",program.ProgramImage.imageURL]]
delegate:self options:SDWebImageProgressiveDownload success:^(UIImage *image, BOOL cached) {
if (image) {
iconCanal = image;
[bgImageicon setImage:iconCanal];
}
[bgImageicon release];
}failure:^(NSError *error) {
[bgImageicon release];
}];
Xcode logs:
<Error>: ImageIO: JPEG Corrupt JPEG data: bad Huffman code
<Error>: ImageIO: JPEG Corrupt JPEG data: premature end of data segment
It seems to be the problem of SDWebImageProgressiveDownload flag. Try to disable it, for example like this:
[[SDWebImageManager sharedManager] downloadWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#&width=300",program.ProgramImage.imageURL]]
delegate:self options:0 success:^(UIImage *image, BOOL cached) {
if (image) {
iconCanal = image;
[bgImageicon setImage:iconCanal];
}
[bgImageicon release];
}failure:^(NSError *error) {
[bgImageicon release];
}];

MFMailComposeViewController: Attaching Images from Photo Gallery

I am having a bit of trouble attaching images from the Photo Gallery to an email.
Basically, one of the features of my application allow the user to take photos. When they snap the shot, I record the URL Reference to the image in Core Data. I understand that you have to go through the ALAssetRepresentation to get to the image. I have this up and running within my application for when the user wants to review an image that they have taken.
I am now attempting to allow the user to attach all of the photos taken for an event to an email. While doing this, I iterate through the Core Data entity that stores the URL References, call a method that returns a UIImage from the ALAssetsLibrary and then attaches it using the NSData/UIImageJPEGRepresentation and MFMailComposeViewController/addAttachmentData methods.
Problem is: When the email is presented to the user, there are small blue squares representing the images and the image is not attached.
Here is the code:
- (void)sendReportReport
{
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:#"Log: Report"];
NSArray *toRecipients = [NSArray arrayWithObjects:#"someone#someco.com", nil];
[mailer setToRecipients:toRecipients];
NSError *error;
NSFetchRequest *fetchPhotos = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Photo" inManagedObjectContext:__managedObjectContext];
[fetchPhotos setEntity:entity];
NSArray *fetchedPhotos = [__managedObjectContext executeFetchRequest:fetchPhotos error:&error];
int counter;
for (NSManagedObject *managedObject in fetchedPhotos ) {
Photo *photo = (Photo *)managedObject;
// UIImage *myImage = [UIImage imageNamed:[NSString stringWithFormat:#"%#.png", counter++]];
NSData *imageData = UIImageJPEGRepresentation([self getImage:photo.referenceURL], 0.5);
// NSData *imageData = UIImagePNGRepresentation([self getImage:photo.referenceURL]);
// [mailer addAttachmentData:imageData mimeType:#"image/jpeg" fileName:[NSString stringWithFormat:#"%i", counter]];
[mailer addAttachmentData:imageData mimeType:#"image/jpeg" fileName:[NSString stringWithFormat:#"a.jpg"]];
counter++;
}
NSString *emailBody = [self getEmailBody];
[mailer setMessageBody:emailBody isHTML:NO];
[self presentModalViewController:mailer animated:YES];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Failure"
message:#"Your device doesn't support the composer sheet"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
and the method that returns the UIImage:
#pragma mark - Get Photo from Asset Library
+ (ALAssetsLibrary *)defaultAssetsLibrary {
static dispatch_once_t pred = 0;
static ALAssetsLibrary *library = nil;
dispatch_once(&pred, ^{
library = [[ALAssetsLibrary alloc] init];
});
return library;
}
- (UIImage *)getImage:(NSString *)URLReference
{
__block UIImage *xPhoto = nil;
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
UIImage *xImage;
// get the image
ALAssetRepresentation *rep = [myasset defaultRepresentation];
CGImageRef iref = [rep fullScreenImage];
if (iref) {
xImage = [UIImage imageWithCGImage:iref];
}
xPhoto = xImage;
};
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror)
{
NSLog(#"Error fetching photo: %#",[myerror localizedDescription]);
};
NSURL *asseturl = [NSURL URLWithString:URLReference];
// create library and set callbacks
ALAssetsLibrary *al = [DetailsViewController defaultAssetsLibrary];
[al assetForURL:asseturl
resultBlock:resultblock
failureBlock:failureblock];
return xPhoto;
}
NOTE: This above code does run, it simply does not attach the image. Also, note, I am able to successfully attach images from the gallery within my application, as long at I have set them into a UIImageView.Image already (basically, I am taking the pointer to the image from the UIImageView and passing it to the addAttachmentData method.) It is just when I attempt to iterate through Core Data and attach without first setting the image into a UIImageView that I have the trouble.
Any tips would be greatly appreciated!
Thanks!
Jason
Oh now I see it.. sry. You are using an asynchronous block to get the image from the asset library. But right after starting that operation, you are returning xImage. But the asynchronous operation will finish later. So you are returning nil.
You need to change your architectur to smth like this:
In your .h file you need two new members:
NSMutableArray* mArrayForImages;
NSInteger mUnfinishedRequests;
In your .m file do smth like that:
- (void)sendReportReport
{
// save image count
mUnfinishedRequests = [fetchedPhotos count];
// get fetchedPhotos
[...]
// first step: load images
for (NSManagedObject *managedObject in fetchedPhotos )
{
[self loadImage:photo.referenceURL];
}
}
Change your getImage method to loadImage:
- (void)loadImage:(NSString *)URLReference
{
NSURL *asseturl = [NSURL URLWithString:URLReference];
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
// get the image
ALAssetRepresentation *rep = [myasset defaultRepresentation];
CGImageRef iref = [rep fullScreenImage];
if (iref) {
[mArrayForImages addObject: [UIImage imageWithCGImage:iref]];
} else {
// handle error
}
[self performSelectorOnMainThread: #selector(imageRequestFinished)];
};
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror)
{
NSLog(#"Error fetching photo: %#",[myerror localizedDescription]);
[self performSelectorOnMainThread: #selector(imageRequestFinished)];
};
// create library and set callbacks
ALAssetsLibrary *al = [DetailsViewController defaultAssetsLibrary];
[al assetForURL:asseturl
resultBlock:resultblock
failureBlock:failureblock];
}
Create a new callback method:
- (void) imageRequestFinished
{
mUnfinishedRequests--;
if(mUnfinishedRequests <= 0)
{
[self sendMail];
}
}
And an extra method for finally sending the mail, after getting the images:
- (void) sendMail
{
// crate mailcomposer etc
[...]
// attach images
for (UIImage *photo in mArrayForImages )
{
NSData *imageData = UIImageJPEGRepresentation(photo, 0.5);
[mailer addAttachmentData:imageData mimeType:#"image/jpeg" fileName:[NSString stringWithFormat:#"a.jpg"]];
}
// send mail
[...]
}

How do I Assign a Name to a Photo Saved in the Photo Library?

I am currently working on a project in which I have to save an image to the photo library and assign a name to each captured image. I know how to save the image, but how do you assign a name to the ones saved in the library?
My code:
-(void)imagePickerController:(UIImagePickerController *) picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissModalViewControllerAnimated:YES];
imageView.image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
imgglobal =imageView.image;
//for saving image in photo library
UIGraphicsBeginImageContext(self.imageView.bounds.size);
[self.imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
UIGraphicsEndImageContext();
UIImage *image1=imageView.image;
[self imageSavedToPhotosAlbum:image1 didFinishSavingWithError:nil contextInfo:nil];
}
- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
NSString *message;
NSString *title;
if (!error) {
title = NSLocalizedString(#"SaveSuccessTitle", #"");
message = NSLocalizedString(#"SaveSuccessMessage", #"");
} else {
title = NSLocalizedString(#"SaveFailedTitle", #"");
message = [error description];
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK", #"")
otherButtonTitles:nil];
[alert show];
[alert release];
}
The photos in the photo library does not contain any names. And you can't create a folder in the photo library either. If you really need a name to the photos, put it inside ~/Documents and implement your own chooser.