Save img with UIImagePickerController - iphone

I am using UIImagePickerController for bring images from the photo library,
i found this method for saving the uiimage as png or jpeg:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
// Create paths to output images
NSString *pngPath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/Test.png"];
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/Test.jpg"];
// Write a UIImage to JPEG with minimum compression (best quality)
// The value 'image' must be a UIImage object
// The value '1.0' represents image compression quality as value from 0.0 to 1.0
[UIImageJPEGRepresentation(image, 1.0) writeToFile:jpgPath atomically:YES];
// Write image to PNG
[UIImagePNGRepresentation(<#UIImage *image#>) writeToFile:jpgPath atomically:YES];
// Let's check to see if files were successfully written...
// Create file manager
NSError *error;
NSFileManager *fileMgr = [NSFileManager defaultManager];
// Point to Document directory
NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
// Write out the contents of home directory to console
NSLog(#"Documents directory: %#", [fileMgr contentsOfDirectoryAtPath:documentsDirectory error:&error]);
[picker release];
}
the problem is that the file in png is 6.4 mb and in jpeg 3.2 mb, there is a way for saving the image file in smaller size then this?

Image returns from camera has 1200*1600 pixal resolution and one pixel is represented by 4 byte. only option to decrease the memory sizeis the resize Image and then compress image in to JPEG or PNG. You can use below method to resize the Image
+ (UIImage*)imageWithImage:(UIImage*)image
scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
...

You can decrease the size of the image by decresing its size
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
[picker dismissModalViewControllerAnimated:YES];
NSData *imageData = UIImageJPEGRepresentation([info objectForKey:#"UIImagePickerControllerOriginalImage"],.5);
UIImage *image = [UIImage imageWithData:imageData];
CGSize size=CGSizeMake(150,150);
UIGraphicsBeginImageContext(size);
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imgView.image =scaledImage; // setting this image imgView"Its a image view" on my view

you could resize image and save image in smaller size.
Here is an example of method for resizing image:
- (void)setThumbnailFromImage:(UIImage *)image {
CGSize origImageSize = [image size];
CGRect newRect;
newRect.origin = CGPointZero;
newRect.size = CGSizeMake(40, 40);
// how do we scale the image?
float ratio = MAX(newRect.size.width/origImageSize.width,
newRect.size.height/origImageSize.height);
// create a bitmap image context
UIGraphicsBeginImageContext(newRect.size);
// Round the corners
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:newRect
cornerRadius:5.0];
[path addClip];
// into what rectangle shall I composite the image?
CGRect projectRect;
projectRect.size.width = ratio * origImageSize.width;
projectRect.size.height = ratio * origImageSize.height;
projectRect.origin.x = (newRect.size.width - projectRect.size.width) / 2.0;
projectRect.origin.y = (newRect.size.height - projectRect.size.height) / 2.0;
// draw the image on it
[image drawInRect:projectRect];
// get the image from the image context, retain it as our thumbnail
UIImage *small = UIGraphicsGetImageFromCurrentImageContext();
[self setThumbnail:small];
// cleanup image contex resources, we're done
UIGraphicsEndImageContext();
}
Hope this will help you! =)

Well, the easiest way is to save it as JPEG and reduce the quality. You set it to 1.0, which results in 3.2 MB, but in my experience a JPEG quality of 0.3 is sufficient for most tasks - you can even read the text in a photo of a newspaper article written with 0.3 quality. The size then is about 700K.
For resizing you should have a look at this excellent article:
http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/

Related

creating a UIImage from a UITableView

Is there a way to create an UIImage out of a UITableView?
I know about this piece of code that will draw a UIImage out of a given UIView:
-(UIImage*) makeImageOutOfView:(UIView*)view {
UIGraphicsBeginImageContext(view.bounds.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;
}
but it would only create an image with the size of the table's frame. I would like to create an image that will display the whole table's content. Another problem is that not only that the created image was limited to the table's frame, but when creating the image after scrolling the table had very weird outcomes (only the visible cells out of the first 6 where shown in the image and that's all, the other visible cells were not drawn..)
EDIT - i want to create an image that was drawn out of the content of a tableView, not setting the tableView's background to display an image..
i just Create a DEMO for you and hope its helps you you can capture table image like this way:-
-(IBAction)savebutn:(id)sender
{
[tbl reloadData];
CGRect frame = tbl.frame;
frame.size.height = tbl.contentSize.height;
tbl.frame = frame;
UIGraphicsBeginImageContext(tbl.bounds.size);
[tbl.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *saveImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *imageData = UIImagePNGRepresentation(saveImage);
NSFileManager *fileMan = [NSFileManager defaultManager];
NSString *fileName = [NSString stringWithFormat:#"%d.png",1];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pdfFileName = [documentsDirectory stringByAppendingPathComponent:fileName];
[fileMan createFileAtPath:pdfFileName contents:imageData attributes:nil];
}
This is a Screen Shot of capture image:-
capture image contain full of table cell top to bottom please download the demo of it:-
http://www.sendspace.com/file/w48sod
One thing you can do is, create an UIView, add all cells one below another you want in the image and finally convert that UIView into an image using the code you have.
I think that should work.
- (UIImage *)imageWithTableView:(UITableView *)tableView{
UIImage* image = nil;
UIGraphicsBeginImageContextWithOptions(tableView.contentSize, NO, 0.0);
CGPoint savedContentOffset = tableView.contentOffset;
CGRect savedFrame = tableView.frame;
tableView.contentOffset = CGPointZero;
tableView.frame = CGRectMake(0, 0, tableView.contentSize.width, tableView.contentSize.height);
[tableView.layer renderInContext: UIGraphicsGetCurrentContext()];
image = UIGraphicsGetImageFromCurrentImageContext();
tableView.contentOffset = savedContentOffset;
tableView.frame = savedFrame;
UIGraphicsEndImageContext();
return image;
}

How to scale image to 0.25 or resize image to 478*640 in iOS6

In my application i have image with dimension 1936*2592 and size upto 6 MB.
i need scale image to 0.25 or resize image to 478*640 and then upload it to server.
I have tried lots of ways to do it in ios6 but failed
imageData= UIImagePNGRepresentation(self.cl_PriviewImage);
UIImage *temp = [[UIImage alloc] initWithData: imageData];
ScaledImage = [temp resizedImage:CGSizeMake(478, 640) interpolationQuality:kCGInterpolationHigh];
ScaledData = UIImagePNGRepresentation( ScaledImage);
//self.cl_PriviewImage is my image
it shows resizedImage method not found.
I have also tried with ScaleToSize method but its showing same error.
i have also tried with
ScaledImage = [UIImage imageWithCGImage:self.cl_PriviewImage.CGImage scale:0.25f orientation:self.cl_PriviewImage.imageOrientation];
ScaledData = UIImagePNGRepresentation(ScaledImage);
in this case there is no error but my purpose didn't get fulfilled i.e uploaded image doesn't get changed in scale/size.
Is there any any other way in iOS 6 or am i wrong some where?
Please suggest me.
Thanks in advance
- (UIImage*) image:(UIImage *) image scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContextWithOptions(newSize, NO, 1);
CGContextSetInterpolationQuality(UIGraphicsGetCurrentContext(), kCGInterpolationHigh);
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
You can also add this method in a UIImage category, that would be a better solution.

Image 90 degrees rotated AVCam

I've looked through tons of questions here in Stackoverflow and none of them solved my problem.
So, I'm using Apple's AVCam sample:
http://developer.apple.com/library/ios/#samplecode/AVCam/Introduction/Intro.html
So, when I take a picture and save it in the image library it's fine, but when I show it in the screen by cropping it and when I send it to a server by using
NSData* pictureData = UIImageJPEGRepresentation(self.snappedPictureView.image, 0.9);
it sends it 90 degrees rotated!
Here is the code I crop it:
UIImage* cropped = [image imageByCroppingRect:CGRectMake(0, 0, (image.size.width * 300)/self.view.frame.size.width, (image.size.height * 300)/self.view.frame.size.height)];
imageByCroppingRect is:
- (UIImage *) imageByCroppingRect:(CGRect)area
{
UIImage *croppedImage;
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], area);
// or use the UIImage wherever you like
croppedImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return croppedImage;
}
When you crop the image, you are loosing the metadata associated with that image telling it the proper way to rotate it.
Instead your code should preserve the original rotation of the image like this:
- (UIImage *) imageByCroppingRect:(CGRect)rect {
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect);
UIImage *result = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation];
CGImageRelease(imageRef);
return result;
}

Low Clarity with ALAsset Thumbnail

I am binding the photo Library images to my Table-view using ALAsset Library.
So whenever i am binding the ALAsset Thumbnail image as a TableView cell image, there is a issue with image Clarity.It Shows as a low clarity image.
I have Created a full resolution image from AlAsset and wrote the thumbnail generation method, i have set the resultant image as table-view image.
After done the above process, i got the full resolution image thumbnail on Table-view.
But the issue was the performance with first time table View image bind process(i used a cache to bind the image after bind first time.So the performance will fast after first time).
So May i know, How can i get the Photo-library full clarity thumbnail image from ALAsset?
I have wrote the below code in MyTableView CellForRowIndexPath is
UIImageView *importMediaSaveImage=[[[UIImageView alloc] init] autorelease];
importMediaSaveImage.frame=CGRectMake(0, 0, 200,135 );
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
CGImageRef iref = [myasset thumbnail];
if (iref) {
importMediaSaveImage.image = [UIImage imageWithCGImage:iref];
}
etc...
I have tried the below method which is time consuming
UIImageView *importMediaSaveImage=[[[UIImageView alloc] init] autorelease];
importMediaSaveImage.frame=CGRectMake(0, 0, 200,135 );
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation *rep = [myasset defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
UIImage *images;
if (iref) {
images = [UIImage imageWithCGImage:iref];
}
NSData *data = [self photolibImageThumbNailData:images];
importMediaSaveImage.image = [UIImage imageWithData:data];
etc....
photolibImageThumbNailData
-(NSData *)photolibImageThumbNailData:(UIImage *)image{
// begin an image context that will essentially "hold" our new image
UIGraphicsBeginImageContext(CGSizeMake(200.0,135.0));
// now redraw our image in a smaller rectangle.
[image drawInRect:CGRectMake(0.0, 0.0, 200.0, 135.0)];
// make a "copy" of the image from the current context
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// now grab the PNG representation of our image
NSData *thumbData = UIImagePNGRepresentation(newImage);
return thumbData;
}
Thanks.
i don't think there is much you can do here.. as those are the only two options we have from ALAsset. you will have to compromise either on quality or time. If you are using the images that you have yourself stored in the library then you can re size them before storing to be a bit smaller to increase the speed of the process.
You should also try [rep fullScreenImage] for a better performant table view but an image with better quality than thumbnail.
You can use
CGImageRef iref = [myasset aspectRatioThumbnail];
and your thumbnail look much better !

Taking a picture from the camera and show it in a UIImageView

I have a view with some fields (name, price, category) and a segmented control, plus this button to take picture.
If I try this on the simulator (no camera) it works properly: I can select the image from the camera roll, edit it and go back to the view, which will show all the fields with their contents .
But on my iphone, when I select the image after the editing and go back to the view, all the fields are empty exept for the UIImageView.I also tried to save the content of the fields in variables and put them back in the "viewWillApper" method, but the app crashes.
Start to thinking that maybe there is something wrong methods below
EDIT
I found the solution here. I defined a new method to the UIImage class. (follow the link for more information).Then I worked on the frame of the UIImageView to adapt itself to the new dimension, in landscape or portrait.
-(IBAction)takePhoto:(id)sender {
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) {
self.imgPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
self.imgPicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
} else {
imgPicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
}
[self presentModalViewController:self.imgPicker animated:YES];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];
NSDate *date = [NSDate date];
NSString *photoName = [dateFormatter stringFromDate:date];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUs erDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png", photoName]];
UIImage *picture = [info objectForKey:UIImagePickerControllerOriginalImage];
// ---------RESIZE CODE--------- //
if (picture.size.width == 1936) {
picture = [picture scaleToSize:CGSizeMake(480.0f, 720.0f)];
} else {
picture = [picture scaleToSize:CGSizeMake(720.0f, 480.0f)];
}
// --------END RESIZE CODE-------- //
photoPreview.image = picture;
// ---------FRAME CODE--------- //
photoPreview.contentMode = UIViewContentModeScaleAspectFit;
CGRect frame = photoPreview.frame;
if (picture.size.width == 480) {
frame.size.width = 111.3;
frame.size.height =167;
} else {
frame.size.width = 167;
frame.size.height =111.3;
}
photoPreview.frame = frame;
// --------END FRAME CODE-------- //
NSData *webData = UIImagePNGRepresentation(picture);
CGImageRelease([picture CGImage]);
[webData writeToFile:imagePath atomically:YES];
imgPicker = nil;
}
Now I have a new issue! If I take a picture in landscape, and try to take another one in portrait, the app crashs. Do I have to release something?
I had the same issue, there is no edited image when using the camera, you must use the original image :
originalimage = [editingInfo objectForKey:UIImagePickerControllerOriginalImage];
if ([editingInfo objectForKey:UIImagePickerControllerMediaMetadata]) {
// test to chek that the camera was used
// especially I fund out htat you then have to rotate the photo
...
If it was cropped when usign the album you have to re-crop it of course :
if ([editingInfo objectForKey:UIImagePickerControllerCropRect] != nil) {
CGRect cropRect = [[editingInfo objectForKey:UIImagePickerControllerCropRect] CGRectValue];
CGImageRef imageRef = CGImageCreateWithImageInRect([originalimage CGImage], cropRect);
chosenimage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
} else {
chosenimage = originalimage;
}
The croprect info is also present for the camera mode, you need to check how you want it to behave.
To Crop image i think this may help you
UIImage *croppedImage = [self imageByCropping:photo.image toRect:tempview.frame];
CGSize size = CGSizeMake(croppedImage.size.height, croppedImage.size.width);
UIGraphicsBeginImageContext(size);
CGPoint pointImg1 = CGPointMake(0,0);
[croppedImage drawAtPoint:pointImg1 ];
[[UIImage imageNamed:appDelegete.strImage] drawInRect:CGRectMake(0,532, 150,80) ];
UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
croppedImage = result;
UIImageView *mainImageView = [[UIImageView alloc] initWithImage:croppedImage];
CGRect clippedRect = CGRectMake(0, 0, croppedImage.size.width, croppedImage.size.height);
CGFloat scaleFactor = 0.5;
UIGraphicsBeginImageContext(CGSizeMake(croppedImage.size.width * scaleFactor, croppedImage.size.height * scaleFactor));
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextClipToRect(currentContext, clippedRect);
//this will automatically scale any CGImage down/up to the required thumbnail side (length) when the CGImage gets drawn into the context on the next line of code
CGContextScaleCTM(currentContext, scaleFactor, scaleFactor);
[mainImageView.layer renderInContext:currentContext];
appDelegete.appphoto = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();