Error when adding an image to an Mail - MFMailComposeViewController - iphone

I'm trying to send an Image, which I have added to my Project, using the MFMailComposeViewController.
I tried this in the simulator and it works fine, I can also see the Image in the Textfield, but when I'm trying to send the Mail, I get the following error on console:
Feb 10 16:22:02 markuss-macbook-pro.speedport.ip RMC Konus[1825] : CGImageCreate: invalid image size: 0 x 0.
My code:
//Get the Image
UIImage *image = [UIImage imageNamed:#"image.png"];
NSData *imageData = UIImagePNGRepresentation(image);
//Create the Mail View
MFMailComposeViewController *mailCV = [[MFMailComposeViewController alloc] init];
[mailCV setMailComposeDelegate:self];
[mailCV addAttachmentData:imageData mimeType:#"image/png" fileName:#"exGraphic.png"];
//Show the View Controller
[self presentViewController:mailCV animated:YES completion:nil];

The problems only appears in the simulator.
I check these code on many different devices and it still works without problems. So I would say, it is a problem of the simulator ...

Return Value of UIImagePNGRepresentation (from apple document)-
A data object containing the PNG data, or nil if there was a problem
generating the data. This function may return nil if the image has no
data or if the underlying CGImageRef contains data in an unsupported
bitmap format.
that means check whether your image is supported for converting it into NSData with png format, because you are receiving NULL here.your error CGImageCreate: invalid image size: 0 x 0. says that it is NULL.
check by changing image . also check without using [UIImage imageNamed:#""] because this method has many disadvantageous.
another one thing, you have converted image.png image into NSData & sending another image exGraphic.png as attachment,check it

Related

Get the name of an image taken from camera/photo library

I am having an issue with getting the name of an image that is taken from the photo library or camera. I have successfully picked the image but I want to send the picked image as an email attachment using MFMailComposeViewController. The problem is that the MFMailComposeViewController required a specific name of the image. I have used the following code to get the image name, and it always returning "assest.JPG" and that is not working with MFMailComposeViewController
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo{
[imageView setImage:image];
image_ = image;
image_ = [UIImage imageNamed:#"file.jpg"];
NSURL *imagePath = [editingInfo objectForKey:#"UIImagePickerControllerReferenceURL"];
imageName = [imagePath lastPathComponent];
NSLog(#"%#",imageName);
[self dismissModalViewControllerAnimated:YES];
if (CAMORLIB == 1) {
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
}}
is there is any other way to deal with this issue?
Thanks,
Mohammed
Your code here:
image_ = image;
image_ = [UIImage imageNamed:#"file.jpg"];
doesn't make sense, as it assigns to image_ twice. The UIImage method -imageNamed:(NSString*)name tries to load a file named file.jpg from disk.
The reason your MFMailComposeViewController doesn't work is that the above code results in image_ being nil because [UIImage imageNamed:#"filename"] doesn't find a file named that (and as a result returns nil)
Attaching to mail
When attaching an image to a MFMailComposeViewController, you tell it what filename you want the image to have, along with the image's data:
NSData* myData = UIImageJPEGRepresentation(image, .70f);
[picker addAttachmentData:myData mimeType:#"image/jpg" fileName:#"desiredfilename.jpg"];
Here, image is a UIImage and #"desiredfilename.jpg" is the filename you want the image to appear to have in the email.
Pulling an image from the Assets Library only gives you the guid url of the item.
There is no real construct of names in the Assets Library. The photo library has a few properties but they are as follows
ALAssetPropertyType
ALAssetPropertyLocation
ALAssetPropertyDuration
ALAssetPropertyOrientation
ALAssetPropertyDate
all of which can be found in AssetsLibrary.framework\ALAsset.h
to put a name for images I gather from there, I usually put
[NSString stringWithFormat:"Image%#.png",imageNumber]
where image number incremented as I add images.
Hope that helps

App works fine on 4S, but crashes on 3G, because of SIGABRT

When the user starts the app for the first time he gets a pop up and has to save an image. It works on the simulator and on the 4S. But when I start it with my 3G it gives me a SIGABRT error as soon as I chose a picture. I assume its because of the size of the picture which is too pick and therefore claiming all of the ram - But that is rather weird, because I make it much smaller. Here is the code:
- (void)viewDidLoad
{
[super viewDidLoad];
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"bild"] == nil) {
picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
}
}
- (void)imagePickerController:(UIImagePickerController *) Picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
double compressionRatio=1;
NSData *imageData=UIImageJPEGRepresentation([info objectForKey:#"bild"],compressionRatio);
while ([imageData length]>5000) {
compressionRatio=compressionRatio*0.20;
imageData=UIImageJPEGRepresentation([info objectForKey:#"bild"],compressionRatio);
}
UIImage *yourUIImage;
yourUIImage = [info objectForKey:UIImagePickerControllerOriginalImage];
imageData = [NSKeyedArchiver archivedDataWithRootObject:yourUIImage];
[[NSUserDefaults standardUserDefaults] setObject:imageData forKey:#"bild"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self dismissModalViewControllerAnimated:YES];
}
I get the SIGABRT error at this line imageData = [NSKeyedArchiver archivedDataWithRootObject:yourUIImage];
Should I use another method to resize the image? Or should I save it as a local file and retrieve it everytime the app starts? (If its possible)
You are using NSCoding to archive an UIImage into a NSData object.
Before iOS5 UIImage didn't implement the methods for NSCoding. You simply can't use archivedDataWithRootObject: with UIImages before iOS5.
That's why you get an exception on the iPhone 3G.
This is just a very educated guess because I can't confirm that with documentation or a test on a device but there are a lot of questions and forum posts around that ask how to implement NSCoding on UIImage.
and this whole block of code isn't called at all because [info objectForKey:#"bild"] will return nil. The info dictionary does not contain an object for the key bild.
Documentation for UIImagePickerControllerDelegate_Protocol contains a List of valid keys
NSData *imageData=UIImageJPEGRepresentation([info objectForKey:#"bild"],compressionRatio);
while ([imageData length]>5000) {
compressionRatio=compressionRatio*0.20;
imageData=UIImageJPEGRepresentation([info objectForKey:#"bild"],compressionRatio);
}
you probably want to use something like that:
NSData *data;
if ([[UIImage class] conformsToProtocol:#protocol(NSCoding)]) {
// >= iOS5
data = [NSKeyedArchiver archivedDataWithRootObject:image];
// save so you know it's an archived UIImage object
}
else {
// < iOS5
data = /* your UIImageJPEGRepresentation method but this time with the key UIImagePickerControllerOriginalImage instead of "bild" */
// save so you know it's raw JPEG data
}
Edit: Another error is probably that you're looking for an object for the key "bild" within the info dictionary you're passed from the image picker controller. It will have no such key. You should pass the key UIImagePickerControllerOriginalImage to get at the image instead.
--
You're not throwing away the old imageData. If your problem is high memory consumption, you'll have to do away with the image data as you progressively shrink the image.
Additionally, an image may be too big anyway to fit within 5000 bytes. Your current code doesn't handle this gracefully. Eventually, the compression ratio will grow beyond 1.0 at which point the function will probably throw an exception.
I'd suggest resizing the image before trying to compress it heavily.
No matter how you make the image data smaller, your current code keeps all the old copies around until the next time the autorelease pool is drained. Since the data returned from UIImageJPEGRepresentation is autoreleased, you may try using an inline autorelease pool around every loop iteration to drain the data immediately.
If the SIGABRT is consistently happening at imageData = [NSKeyedArchiver archivedDataWithRootObject:yourUIImage]; then my feeling would be that it is likely to be that specific line, rather than a memory issue.
UIImage never used to conform to NSCoding, but the current docs say that it does. It could be that the 3G, which will be limited to iOS 4.2.1 is using a non-conformant version and so crashes when you try to archive, whereas the 4S on iOS 5 uses the new conformant version.
Try adding a category for NSCoding to UIImage and then rerun on the 3G. Example at http://iphonedevelopment.blogspot.com/2009/03/uiimage-and-nscoding.html

How do I read in & display a local image on UIImageView via SQLite

How may I modify, read in an image path from SQLite DB, & display it via an UIImageView? In other words, this application will work in offline mode & i have the images at hand. How will i go about this then, tgt with sqlite? (retrieve images by storing their image path name # sqlite)
Sample code I have for now:
- (void)viewDidLoad
{
[super viewDidLoad];
appDelegate = (SQLAppDelegate *)[[UIApplication sharedApplication] delegate];
//start with index 0
currentStepIndex = 0;
Resolution *resolutionObj = [appDelegate.resolutionArray objectAtIndex:currentStepIndex];
[resolutionDescription setText:resolutionObj.stepDescription];
//checking for null string
//replicate of ifelse #goToNextStep & #goToLastStep (needed for initial load of image)
if (resolutionObj.imageDescription != NULL)
{
//if goes in here, then image description is not null
NSURL *imageURL = [NSURL URLWithString:resolutionObj.imageDescription];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
[resolutionImage setImage:[UIImage imageWithData:imageData]];
}
else
{
//if goes in here, then image description is NULL
//show empty image
[resolutionImage setImage:NULL];
}
}
You are missing a lot the way I see it. If your images are coming from a website then you should use a webView to display it. If you are planning to display images in UIImageView, you should first download them onto your device from the url that points to that image and save it in the sandbox. Then you store the path of this downloaded image in your sqlitedb. Now when you want to load this image you just access this image using the path that you have in your sqlitedb and render it. How do you think by just saving the imageName image013.png and not downloading the image itself will render the image for you in UIImageView. Just think where your UIImageView will go and find this image if it's not already downloaded onto your device. For going and finding on the web directly, you need a UIWebView and not an UIImageView
If you are packaging your images as resources with your app binary, you can load them as shown below:
UIImage *img = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"myimagefile" ofType:#"png"]];
[self.testView.imgView setImage:img];
where myimagefile is the name of your file and ofType is the type of image. .png or .jpg or whatever.
If you have anymore doubts. Please come back.

Dynamically loading images in UIImageView from database in objective c

I have saved my images in database with type BLOB. Now I am extracting these images from database using sql stmt and saving it in a NSData object. see the following code snippet
NSData *img = [[NSData alloc] initWithBytes:sqlite3_column_blob(loadInfostmt, 4) length: sqlite3_column_bytes(loadInfostmt, 4)];
self.birdImage = [UIImage imageWithData:img];
After getting image I tried setting it at image attribute of UIImageView to load it to image view. I used following techniques but nothing seems to work.
1.
self.imgPikr = [[UIImageView alloc] initWithImage:brd.birdImage];
[self.imgPikr setImage:brd.birdImage];
2.
[self.imgPikr = [[UIImageView alloc] init];
self.imgpikr.image = brd.birdImage;
3.
[self.imgPikr = [[UIImageView alloc] init];
[self.imgpikr setImage:brd.birdImage];
Here imgPikr is a UIImageView object and birdImage is object of UIImage class.
every other data is displayed in view correctly except the image.
I dont have any error or warning or runtime exception but still cant load image.
Please tell me the solution. I have been working on it since a week. but couldnt find anything working.
Any answer or experimentation is welcomed.
thanx in advance
Option 1 is the best option, since -[UIImageView initWithImage:] will automatically resize the imageView to be the same size as the passed image (and it is also unnecessary to setImage: if you use this initializer).
However, as #Robot K points out in the comments, you still need to add self.imgPikr as a subview of a view that is visible on the screen.
Additionally, if your imgPikr property is declared as (retain), then you have a memory leak.

Table image not showing, "Pop an autorelease pool" error

I have a UITableView which uses the following code to display an image in a Table View cell:
cell.imageView.layer.masksToBounds = YES;
cell.imageView.layer.cornerRadius = 5.0;
UIImage *image = [UIImage imageNamed:[[color types] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
if ( image ) {
cell.imageView.image = [image imageScaledToSize:CGSizeMake(50, 50)];
}
It works fine on the iPhone simulator, but when I try it on a real iPhone the iPhone doesn't show. Instead in the console in debugging mode, I get this error:
attempt to pop an unknown autorelease
pool (0x851e00)
Any help would be great, thanks.
Check that image != nil. If it == nil then problem in that [[color types] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] code.
Generated file name must be equal real file name including extension, case and must not contain whitespaces.