UIGraphicsGetImageFromCurrentImageContext rotate the image at will? - iphone

In brief, the app is meant to do the following:
The user will select from the photos within the iPhone (via ALAssets). This part is fine.
The selected photo will appear on another view, within a smaller, rectangular subview.
When using the ALAsset thumbnail, the image shows up correctly within the subview. However, the resolution is poor, so I'm trying to use a higher resolution image.
When using the full resolution image, and then placing it into the view, any portrait photo will be rotated 90 degrees counter-clockwise.
Code-wise, this it looks like this:
//ImageView is the UIImageView subview that will hold the selected photo image.
//This code works ok, but I'd rather have a higher resolution photo.
[imageView setClipsToBounds:YES];
[imageView setContentMode:UIViewContentModeScaleAspectFill];
[imageView setImage:[UIImage imageWithCGImage:[selectedPhoto thumbnail]];
Now, this is the code where I try to use a higher resolution image, but then the image within imageView is rotated -90 degrees:
[imageView setClipsToBounds:YES];
[imageView setContentMode:UIViewContentModeScaleAspectFill];
//HIGH RESOLUTION IMAGE
ALAssetRepresentation *rep = [selectedPhoto defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
if (iref)
{
UIImage *largeImage = [Utilities imageWithImage:[UIImage imageWithCGImage:iref] scaledToSize:CGSizeMake(CGImageGetWidth(iref)/4, CGImageGetHeight(iref)/4)];
[imageView setImage:largeImage];
}
And the imageWithImage: function called there looks like this:
+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
As mentioned, photos taken in landscape orientation by the iPhone camera come out OK. However, photos taken in portrait camera orientation come out rotated -90 degrees somehow.
How can I make it so that each photo, whether taken in portrait or landscape, will come out oriented correctly on my ImageView?
Any help would be appreciated! Thank you!

I found the answer here!
ALAssetRepresentation fullResolutionImage's UIImageOrientation is wrong
I am doing this now:
UIImage *largeImage = [[UIImage alloc] initWithCGImage:iref scale:4 orientation:(UIImageOrientation)rep.orientation];

Related

Maintain image resolution in screen grab

In my app, the user is able to put stickers on top of a photo. When they go to save their creation, I do a screen grab and store it in a UIImage:
UIGraphicsBeginImageContextWithOptions(self.mainView.bounds.size, NO, [UIScreen mainScreen].scale);
[self.mainView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *resultImage = [UIGraphicsGetImageFromCurrentImageContext() retain];
UIGraphicsEndImageContext();
(where self.mainView has a subview UIImageView which holds the photo, and another subview UIView which holds the stickers).
I am wondering, is it possible to do a screen shot in this manner, and maintain the resolution of the aforementioned photo?
The following will 'flatten' two UIImages into one while maintaining the resolution of the original image(s):
CGSize photoSize = photoImage.size;
UIGraphicsBeginImageContextWithOptions(photoSize, NO, 0.0);
CGRect photoRect = CGRectMake(0, 0, photoSize.width, photoSize.height);
// Add the original photo into the context
[photoImage drawInRect:photoRect];
// Add the sticker image with its upper left corner set to where the user placed it
[stickerImage drawAtPoint:stickerView.frame.origin];
// Get the resulting 'flattened' image
UIImage *flattenedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
The above assumes photoImage and stickerImage are both instances of UIImage and stickerView is a UIView with containing the stickerImage and thus will be able to use the stickerView frame to determine its origin.
If you have multiple stickers, just iterate through the collection.
If you are looking to save an image of your current view then this might help you.
UIGraphicsBeginImageContext(self.scrollView.contentSize);
[self.scrollView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRef imageRef = CGImageCreateWithImageInRect(finalImage.CGImage,
CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y,
scrollView.frame.size.width, scrollView.frame.size.height));
UIImage *screenImage = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
CGImageRelease(imageRef);

Still Image using AVCaptureDevice with overlay image

I am developing an iPhone app in which I am capturing the live video.
I have added the AVCaptureVideoPreviewLayer to the self.view.layer as sublayer.
[self.view.layer addSublayer: self.prevLayer];
On the same self.view I have added an image as subview.
[self.view addSubView:image];
Now what I want is to capture an image from the live video but the image should also come into that picture as it looks on the screen.
I have tried to take the screen shot but it capture only the image and not the live video image.
Can any body please help me on this.
Thanks in advance.
hi this will help you as it works for me
- (void)didTakePicture:(UIImage *)picture
{
UIImage *frm = self.overlayViewController.imgOverlay.image;
NSLog(#"width %f height %f",picture.size.width,picture.size.height);
UIGraphicsBeginImageContext(picture.size);
[picture drawAtPoint:CGPointMake(0,0)];
[frm drawInRect:CGRectMake(0, 0, picture.size.width, picture.size.height)];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSLog(#"view %#",viewImage.debugDescription);
[self.capturedImages addObject:viewImage];
}

Creating our own crop rect in camera overlay

I want to state my basic requirement which is to change the frame for crop rect in UIImagePickerController for a camera.
I just realized that it is not possible to change frame for crop rect. That leaves me with only one option i.e to create my own camera overlay wherein I can set frame for crop rect. I searched a lot but found nothing. I asked previously but didn't get anything. I don't even know is it possible and if yes then how to create it and move the crop box, scale it in accordance to default UIImagePickerController crop rect.
You have to Implement your own CropRect. First set the
[picker setAllowsEditing:NO];
Then in didFinishPickingMediaWithInfo delegate Push your own CropRect View
CustomImageEditor *custom = [[CustomImageEditor alloc] initWithNibName:#"CustomImageEditor" bundle:nil];
[picker pushViewController:custom animated:YES];
[custom release];
while Pushing view pass the image to the Custom View like this
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
custom.pickedImage = image;
In that customView you crop the image.
For croping the image try like this..
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropRect);
UIImage *image = [UIImage imageWithCGImage:imageRef];

iPhone taking a picture when saving always landscape

I have this iPhone application that let users take a picture and save it in a database online. My problem is that every time an user take a picture and saves it, the picture results to be in landscape, even though it was taken in portrait mode. This results in having the portrait picture stretched.
This is the code I use when taking a picture:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];
NSData *imgData=UIImageJPEGRepresentation([info objectForKey:#"UIImagePickerControllerOriginalImage"],1);
UIImage *img=[[UIImage alloc] initWithData:imgData];
if(img.size.width < img.size.height){
NSLog(#"width < height");
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
}
else{
NSLog(#"width > height");
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 460, 320)];
}
imageView.image = img;
[img release];
[[self view] fillPreviewWithImg: imageView];
[[self view] setImage: imageView.image];
}
Basically what I do is take the picture, create a UIImage, check if it's portrait or landscape, create the corresponding UIImageView and then set the image into the UIImageView. After that I just call a couple of methods to set up the image in the main view.
I believe the problem with stretching is not bounded to the PHP but to the Objective-C code, but I can't really see how or why this behavior happens.
Does anyone of you have an idea?
Thanks,
Masiar
Have a look at the imageOrientation property of the UIImage class. You can have an image that is 320 wide and 480 high, but with an orientation of Landscape. This is contained in the EXIF information and it is up to the viewing program to use this orientation information to rotate the image appropriately. Just checking the width and height of the image is not sufficient to know the orientation and this is causing your stretching that you are seeing.

iOS Retina Display Masking Bug

I'm currently using two images for a menu that I've built. I was using this code a while ago for normal display systems and it was working fine, with the retina display I'm having some issues with CGImageRef creating the right masked image on a depress for the background display. I've tried importing using the Image extensions for retina images. The images are supplied using:
[UIImage imageNamed:#"filename.png"]
I've provided both a standard and a retina image with both the filename.png and the filename#2x.png names.
The problem comes when choosing the mask for the selected area. The code works fine with lower resolution resources, and a high resolution main resource, but when I use
CGImageCreateWithImageInRect
And specify the rect that I want to create the image within, the image's scale is increased meaning that the main button's resolution is fine, but the image that is returned and superimposed on the button downpress is not the correct resolution, but oddly scaled to twice the pixel density, which looks terrible.
I've tried both
UIImage *img2 = [UIImage imageWithCGImage:cgImg scale:[img scale] orientation:[img imageOrientation]];
UIImage *scaledImage = [UIImage imageWithCGImage:[img2 CGImage] scale:4.0 orientation:UIImageOrientationUp];
And I seem to be getting nowhere when I take the image and drawInRect:(Selected Rect)
I have been tearing my hair out for about 2 hours now, and can't seem to find a decent solution, does anyone have any ideas?
I figured out what is necessary to be done in this instance. I created a helper method that would take the scale of the image into account when building the pressed state image and made it scale the CGRect by the image scale like so
- (UIImage *)imageFromImage:(UIImage *)image inRect:(CGRect)rect {
rect.size.height = rect.size.height * [image scale];
rect.size.width = rect.size.width * [image scale];
rect.origin.x = rect.origin.x * [image scale];
rect.origin.y = rect.origin.y * [image scale];
CGImageRef sourceImageRef = [image CGImage];
CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect);
UIImage *newImage = [UIImage imageWithCGImage:newImageRef scale:[image scale] orientation:[image imageOrientation]];
CGImageRelease(newImageRef);
return newImage;
}
That should fix anyone having similar issues for mapping.