While the following code is saving the image I took from my application into the camera roll. I am trying to figure out how to update the thumbnail image that displays in the left corner next to the take image button when you first launch the camera to be the image that I saved. Shouldn't it always be the last image added to the camera roll? Here is how I am saving it:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *originalImage = [info valueForKey:UIImagePickerControllerOriginalImage];
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
UIImageWriteToSavedPhotosAlbum(originalImage, nil, nil, nil);
}
}
I'm pretty sure there's nothing you can do to change that thumbnail; it's the Camera app's business what goes in there. At any rate, I think it is defined to contain a thumbnail of the last photo you took using the camera app.
I just tried this:
Launch Camera. Take a photo.
Launch Safari. Save an image from a page.
Launch Camera. The thumbnail is the photo I took, not the saved image.
I say either let it be or file a bug with Apple if you feel the behavior is incorrect.
Related
Currently I am developing an app in which I want to get photo album saved video and then show selected
video in image view & then later on send this video to Facebook. I successfully open the photo album
but now how can i save selected video in image view of app.
I think you have used UIImagePickerController to open the photo album (mediaType will be kUTTypeMovie)
Use the below UIImagePickerController delegate to get the videoUrl and Its thumbnail
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *videoURL = [info valueForKey:UIImagePickerControllerReferenceURL];
UIImage *videoThumbnail = [info valueForKey:UIImagePickerControllerOriginalImage];
You can save the videoURL and retrieve the Video later using ALAsset_Class or even you can set the url to moviePlayer. [moviePlayer setContentURL:movieURL];
You can use the videoThumbnail to deal with UiImages
Finally, do a Google search to Share video to Facebook.
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.
I've been working on a simple application which allows the user to take a photo and store it in the camera roll for later use. To do this, I am using a UIImagePickerController, and the method UIImageWriteToSavedPhotosAlbum, which is working perfectly.
My question is: Is there any way to store the path to the image in the Camera Roll so that I can use that to call the image again later? Or, do I have to save the image in the app in order to use it again later?
It would be great if there was a simple way to do this, as there is with a video where you just store the NSUrl for the particular video, and then call MPMoviePlayerController to do everything for you.
Any help would be much appreciated!
It turns out that it is actually not that hard to do this. In the UIImagePickerDelegate method:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info;
the NSDictionary "info" actually contains the url to the image or the movie which is stored on the Camera Roll. You need only check:
if([[info valueForKey:UIImagePickerControllerMediaType] isEqualToString:(NSString *)kUTTypeMovie]){ // If the user took a video,
movieURL = [[info valueForKey:UIImagePickerControllerMediaURL] retain];// Get the URL of where the movie is stored.
UISaveVideoAtPathToSavedPhotosAlbum([movieURL path], nil, nil, nil); // Save the movie to the photo album.
}
and this will save the movie to the Camera Roll, as well as record the url. Doing it for a photo is analogous, just replace the "kUTTypeMovie" with "kUTTypeImage", and replace
movieURL = [[info valueForKey:UIImagePickerControllerMediaURL] retain];// Get the URL of where the movie is stored.
UISaveVideoAtPathToSavedPhotosAlbum([movieURL path], nil, nil, nil); // Save the movie to the photo album.
with
UIImage * image = [info valueForKey:UIImagePickerControllerOriginalImage];
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
If you need to store the UIImage not on the Camera Roll, there is a great post on stackoverflow Saving UIImage with NSCoding that you can use to store the image in your app. Hope that helps someone!
Hey, I know that when a user selects a Video I do get a URL for the video.... but can you direct me to a proper implementation because my App just sticks there when I click choose in the simulator and I cannot navigate away from the Video Player page....
Any good tutorial on this?
Once you select the video - execution flows to the following function:
(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
.... code here .....
//get the videoURL
NSString* videoURL= [info objectForKey:UIImagePickerControllerMediaURL];
//IMPORTANT: remember to test that the video is compatible for saving to the photos album
UISaveVideoAtPathToSavedPhotosAlbum(videoURL, self, #selector(video:didFinishSavingWithError:contextInfo:), nil);
.... code here .....
}
Take a look into 'UISaveVideoAtPathToSavedPhotosAlbum' specifically. This allows saving to the camera roll.
I am making an app that adds a picture frame to a photo.
I would like to know how to have my Save button save both Images (the photo, and the frame) as one Image.
Right now it only saves one of the images.
In interface builder I have the save action saving the image that is loaded into an ImageView, with the frame ImageView overlaying that image.
I'd like to merge the two photos as one, so the save action can save the image with the frame.
Thanks!
If you've displayed the frame over the photo in your UI, just use UIScreenGetImage something like
...
CGImageRef screen = UIGetScreenImage();
UIImage* image = [UIImage imageWithCGImage:screen];
CGImageRelease(screen);
// You could, e.g., save the captured image to photo album
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
This probably isn't what you want, but if you load both images into OpenGL (there's a nice Apple sample that loads images in OpenGL), lay one on top of the other, and then write the result to an image (excellent tutorial here - http://www.bit-101.com/blog/?p=1861).
You don't even need to render it to the screen, so there's no fiddling around with EAGL.