How to programmatically take a low resolution snapshot using camera? - iphone

I am developing a fax client that is able to take snapshots. It communicates to the server via web service calls. Is there a way to reduce the image resolution so that we can have faster uploads and downloads? Right now the user has to wait a good 50 seconds for anything to happen.
This is the code I am using presently:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
[image setImage:img];
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
}

You have to resize the image the ImagePickerController gives you before you send it. You can find many informations and UIImage categories on this article : http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/

Related

Speed up UIImagePickerController by using a low res image then later swapping in the high res image

There is a great wiki about image loading from the camera picker. Which made me aware of costs of taking an image at full resolution.
At the moment, when a photo is picked, I push a new view controller and display the image at full resolution. Pushing the view is a really slow and choppy experience (about 1 fps!) that I want to smooth out. Comparing to picking a photo on Instagram, I notice that they use a low resolution image and later swap in the full image. (I need the full res image because the user should be able to zoom and pan)
The idea I want is somthing like this:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage* fullImage = [info objectForKey:UIImagePickerControllerOriginalImage];
// Push a view controller and give it the image.....
}
- (void) viewDidLoad {
CGSize smallerImageSize = _imageView.bounds;
UIImage* smallerImage = [MyHelper quickAndDirtyImageResize:_fullImage
toSize:smallerImageSize];
// Set the low res image for now... then later swap in the high res
_imageView.image = smallerImage;
// Swap in high res image async
// This is the part im unsure about... Im sure UIKit isn't thread-safe!
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, NULL), ^{
_imageView.image = _fullImage;
});
}
I think that UIImage isn't memory mapped in until it is used. Therefore it dons't slow things down until its given to the imageView. Is this correct?
I think image decoding is already done asynchronously by the system, however, it is sill slowing the phone down considerably while its loading.
Is there a way do perform some of the work required to display an image in a very low priority background queue?
You're trying to do things the most complicated way :)
Why not just prepare the small image before pushing the view controller and pass it to them? Look at this code:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *fullImage = [info objectForKey:UIImagePickerControllerOriginalImage];
UIImage *smallImage = [fullImage imageScaledToSize:self.view.bounds];
// Push a view controller and give it BOTH images
}
// And in your pushed view controller
- (void)viewDidLoad
{
_imageView.image = self.smallImage;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
_imageView.image = self.fullImage;
}
The main thing is that viewDidAppear: will be called right after the animation is done so you can switch images here without any worries.
In addition to Andrey's answer, instead of using imageScaledToSize, use CGImageSourceCreateThumbnailAtIndex. In fact, it's very possible (I am pretty sure it's the case) that any image used in the photo album already has a thumbnail. So instead of bothering with the image itself, grab the existing thumbnail and display it, then use Andrey's code to switch in the main image. This way you do as little work as possible during the animation period.
Calling CGImageSourceCreateThumbnailAtIndex will return the thumbnail image, whether it's already there or needs to be generated. So it'll be quite safe to use, and probably at least as fast as imageScaledToSize.
You can find complete code samples to use it in the Apple docs, no need to duplicate it here.
Have you tried using ALAssetsLibrary to load the thumbnail of that image instead of trying to load the image at full resolution? It's faster than resize it as well.

ABPersonSetImageData is extremely slow

I am writing an app that interfaces with the iPhone address book.
Here is the relevant section of my code (from UIImagePickerControllerDelegate)
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
ABPersonSetImageData(record, (__bridge CFDataRef)UIImagePNGRepresentation(image), &error);
}
My app lets you take a picture with the camera (using UIImagePictureController), and then stores it as the contact for someone in your address book.
I'm finding that the operation above hangs for 5-10 seconds. 1) Is there a better approach? 2) Why is this so slow?
Saving as a JPEG:
UIImageJPEGRepresentation (UIImage *image, CGFloat compressionQuality);
will be faster than UIImagePNGRepresentation, especially if compressionQuality is set to a low value. However, this is still a CPU intensive process, so there's no way to avoid the wait.
The best you can do is show a message that work is being done, so the interface doesn't feel unresponsive. Use something like SVProgressHUD to do that.

How to use the picture takes from camera?

Iam developing one application.In that i want to take the picture from camera.For that i used the UIImagePickerControllerSourceTypeCamera.But my problem is how to get that image intomy application.Please tell me how to manage that one.
Thats pretty simple. You have a method in UIImagePickerController which is
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImageWithMediaInfo(NSDictionary *)info. You can get here the image user had selected from UIImagePickerControllerSourceTypeCamera. Now declare an object of UIImage in the header of your AppDelegate. For example I declare UIImage *pickedImage. The purpose to declare this in AppDelegate is that we can use this Image anywhere in our app. Dont retain and synthesize this object. Now come back to your didFinishPickingImage method and now your body of this method should look like this:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)info {
((AppDelegate*)[UIApplication sharedApplication].delegate).pickedImage= [info objectForKey: UIImagePickerControllerOriginalImage];
}
Now you can easily use this image all over your app by just calling ((AppDelegate*)[UIApplication sharedApplication].delegate).pickedImage. Hope it helps.
Happy Coding!

Getting cropped Image from camera in iphone

I am working on a app where i need to get a image from camera but before that i want to allow cropping of the image. I am using UIImagePickerControllerCropRect in UiImagePicker to get the cropped rectangle. I am able to get the original image from the picker but i am not able to crop it using UIImagePickerControllerCropRect. Can someone help me?
Thanks
this support question is similar http://discussions.apple.com/thread.jspa?threadID=1808549
Try using Below code
Use Below mentioned Delegate Method to get Image
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
//you will get image here which is already cropped...
// This will work iOS 3.2 or later
}
Hope this will work for you. Though I haven't tried full code yet But it is giving me scaled Size

IPhone - UIImage to Binary String

I have this bit of code that get the image i have picked from the Camera and displays it into a UIImageView. I want to convert the image to a binary string so i can then make a URL call and pass it back to the server. How would I modify this code to get my binary string?
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo {
imageView.image = image;
[picker dismissModalViewControllerAnimated:YES];
}
You should better pass the NSData got from image jpeg representation to the server by POST method.
Marco
You can find an example of how to do it from Apple in this technote. Not as easy as it should be, but appears that it's the only way to do it. Is it possible for you to get the data before it becomes a UIImage to make your life a little easier? If not, just try the method presented at the link.