I have divergent needs for the image returned from the iPhone camera. My app scales the image down for upload and display and, recently, I added the ability to save the image to the Photos app.
At first I was assigning the returned value to two separate variables, but it turned out that they were sharing the same object, so I was getting two scaled-down images instead of having one at full scale.
After figuring out that you can't do UIImage *copyImage = [myImage copy];
, I made a copy using imageWithCGImage, per below. Unfortunately, this doesn't work because the copy (here croppedImage) ends up rotated 90º from the original.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Resize, crop, and correct orientation issues
self.originalImage = [info valueForKey:@"UIImagePickerControllerOriginalImage"];
UIImageWriteToSavedPhotosAlbum(originalImage, nil, nil, nil);
UIImage *smallImage = [UIImage imageWithCGImage:[originalImage CGImage]]; // UIImage doesn't conform to NSCopy
// This method is from a category on UIImage based on this discussion:
// http://discussions.apple.com/message.jspa?messageID=7276709
// It doesn't rotate smallImage, though: while imageWithCGImage returns
// a rotated CGImage, the UIImageOrientation remains at UIImageOrientationUp!
UIImage *fixedImage = [smallImage scaleAndRotateImageFromImagePickerWithLongestSide:480];
...
}
Is there a way to copy the UIImagePickerControllerOriginalImage image without modifying it in the process?
This seems to work but you might face some memory problems depending on what you do with newImage:
Copy backing data and rotate it
This question asks a common question about
UIImage
in a slightly different way. Essentially, you have two related problems - deep copying and rotation. AUIImage
is just a container and has an orientation property that is used for display. AUIImage
can contain its backing data as aCGImage
orCIImage
, but most often as aCGImage
. TheCGImage
is a struct of information that includes a pointer to the underlying data and if you read the docs, copying the struct does not copy the data. So...Deep copying
As I'll get to in the next paragraph deep copying the data will leave the image rotated because the image is rotated in the underlying data.
This will copy the data but will require setting the orientation property before handing it to something like
UIImageView
for proper display.Another way to deep copy would be to draw into the context and grab the result. Assume a zebra.
Deep copy and Rotation
Rotating a
CGImage
has been already been answered. It also happens that this rotated image is a newCGImage
that can be used to create aUIImage
.I think you need to create an image context (CGContextRef). Draw the UIImage.CGImage into the context with method CGContextDrawImage(...), then get the image from the context with CGBitmapContextCreateImage(...). With such routine, I'm sure you can get the real copy of the image you want. Hope it's helped you.
This should work: