Image rotating left when taking picture with iPad - objective-c

In the application I'm working at you can take a picture with the iPad camera. After that using CoreGraphics you can draw shapes on that image.
At first the image was upside down and mirrored. I resolved that with this:
CGContextTranslateCTM(myContext, 0, backgroundImage.size.height);
CGContextScaleCTM(myContext, 1.0, -1.0);
But now when you take the image in portrait mode, the imported image is rotated to the left (so it's presented horizontally). I rotated the image back with this code:
UIImage *tempImage = [[UIImage alloc] initWithCGImage:imagetest.CGImage];
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformTranslate(transform, 0, tempImage.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
CGContextRef ctx = CGBitmapContextCreate(NULL, tempImage.size.width, tempImage.size.height,
CGImageGetBitsPerComponent(tempImage.CGImage), 0,
CGImageGetColorSpace(tempImage.CGImage),
CGImageGetBitmapInfo(tempImage.CGImage));
CGContextConcatCTM(ctx, transform);
CGContextDrawImage(ctx, CGRectMake(0,0,tempImage.size.height,tempImage.size.width), tempImage.CGImage);
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
Now the image is shown in the right way (portrait), but I can't draw properly on it, maybe because the width and height are reversed.
From what I read there is a meta tag with the image orientation that cannot be read by CoreGraphics.
Do you know a better way to rotate the image? Or any solution that would keep the image from rotating when taking a photo in portrait mode?

Yes that is an issue because default orientation of device camera is Landscape, if you take picture in portrait mode and see preview in Photo Gallery it will be fine, but as you use it in your app it will be rotated 90 Degrees, to fix that issue i have written answer in my Recent Post Here

If you tell the image to draw itself, it will respect its own orientation. No need to flip it (it does that itself) and no need to rotate it.

Related

Print view larger than screen to PDF

I can print a nice perfect Report on iPad, but now we want to port our app to iPhones, too.
All normal views are being printed as they have to, except the one view where we use ShinobiCharts (OpenGL): on iPhone only the screensize will be printed, the rest of the PDF-Sheet will remain white.
I tried putting it into a scrollview and programatically assign the right resolution to the view before it was printed, but this resulted in the small window being streched to fit the PDF-Sheet's size, still not displaying the whole diagrams.
Normal views:
UIGraphicsBeginPDFPage();
[pdf1.view.layer renderInContext:pdfContext];
Diagram view:
UIGraphicsBeginPDFPage();
UIGraphicsBeginImageContextWithOptions(pdf8.view.bounds.size, NO, 0.0);
[pdf8.view drawViewHierarchyInRect:pdf8.view.bounds afterScreenUpdates:YES];
UIImage *pdf8Image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *pdf8ImageView = [[UIImageView alloc] initWithImage:pdf8Image];
[pdf8ImageView.layer renderInContext:pdfContext];
Full image on iPad
Cropped image without ScrollView
Scaled image with ScrollView

renderInContext on retina and non-retina devices

I am creating a PDF by taking a screenshot of a UIView, this is currently working great on the iPad3 with the retina display, but when testing on other devices with lower resolution screens I am having problems with text resolution.
Here is my code:
//start a new page with default size and info
//this can be changed later to include extra info.
UIGraphicsBeginPDFPage();
//render the view's layer into an image context
//the last option specifies scale. If 0, it uses the devices scale.
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 2.0);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//render the screenshot into the pdf page CGContext
[screenShot drawInRect:view.bounds];
//close the pdf context (saves the pdf to the NSData object)
UIGraphicsEndPDFContext();
I have also tried to set the UIGraphicsBeginImageContextWithOptions scale to 2.0, but this gives no change. How can I force a view on an iPad2 to render at 2x resolution?
Expected output:
Actual output:
I ended up fixing this by recursively setting the contentScaleFactor property of the parent view and its subviews to 2.0.
The UIImage was rendering at the correct resolution, but the layer wasn't when renderInContext was being called.

Get image data for resizableImageWithCapInsets: after being resized

I have a png that I'm using as an image mask for another image. Both image have rounded corners that are being preserved with resizableImageWithCapInsets:. The image (not the mask) is being sized automatically because it is the progressImage of a UIProgressView.
The problem I'm having is that if I use CGImageMaskCreate to create a mask and simply give it the width of of the width of the UIProgressView, the mask image is being stretched (ie, it does not preserve the caps).
What I'd like to do is create a new UIImage with resizable caps, manually resize the image (perhaps by putting it in a UIImageView), get the data representation of the resized version of the mask image, then create a new image with that data and use that image as the mask. It seems, though, that even if I create a UIImageView with the image, and then set the frame of the UIImageView appropriately, getting the image back out of the view gives my original image.
Is there any way to get the result of a resizableImageWithCapInsets: image without it actually being drawn into the UI?
I would try drawing image piece by piece into CGContext where you can access data provider or extract NSData through creating UIImage
- (UIImage*) drawImage:(UIImage *)image
atSize:(CGSize) size
{
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
CGImageRef cgImage = CGBitmapContextCreateImage(context);
UIImage *outImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
UIGraphicsEndImageContext();
return outImage;
}

UIImageView, CGImage, and Retina Art

I've got a few CALayers in my interface, and I'm drawing images directly to the layers as opposed to imageViews.
Here's a snippet:
UIImage *anImage = [UIImage imageNamed:#"anyImage"];
CGImageRef anImageRef = [anImage CGImage];
CALayer *aLayer = [CALayer layer];
CGFloat anImageWidth = CGImageGetWidth(anImageRef);
CGFloat anImageHeight = CGImageGetHeight(anImageRef);
CGRect layerFrame = CGRectMake(0,0,anImageWidth, anImageHeight);
[aLayer setLayerContents:(__bridge id)anImageRef];
[parentLayer addSublayer:aLayer];
So my problem is that I'm getting inconsistent results with the size of the image. On the retina Device, the image that appears is double the size anticipated (e.g., it matches the pixel size of the #2x image). On the simulator in retina mode, the image drawn to the layer is the anticipated size (where points match the pixels of the non retina image).
Rather than statically set the size, or halve the size (which corrects the issue on the device but breaks compatibility with non-retina displays), what is a good solution or workaround to this scenario? Why is it happening?
The UIImage contains a scale property. It will be 2.0 for retina display images. See the docs for more info.
CGImageGetWidth() and CGImageGetHeight() return the number of pixels whereas you need the image size in points. Use -[UIImage size] instead.

Creating thumbnail for an image grid

I'm building an app like the photo app by apple in the iPad. I have large full-screen image and I show them using a scrollView for managing zooming and paging. The main problem happen when I try to create a grid with the thumbnail of the images. I create them as UIImageView overlapped on a UIButton. All works great, but when I try the app on the iPad, it requires a lot of memory, I suppose it depend on the rescaling of the Image. There's a way to create a UIImageView with the little image,rescaling the larger image, without using so much memory?
You can use UIGraphics to create a thumbnail. Here's this code to do it:
UIGraphicsBeginImageContext(CGSizeMake(length, length));
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextClipToRect( currentContext, clippedRect);
CGFloat scaleFactor = length/sideFull;
if (widthGreaterThanHeight) {
//a landscape image – make context shift the original image to the left when drawn into the context
CGContextTranslateCTM(currentContext, -((mainImage.size.width - sideFull) / 2) * scaleFactor, 0);
}
else {
//a portfolio image – make context shift the original image upwards when drawn into the context
CGContextTranslateCTM(currentContext, 0, -((mainImage.size.height - sideFull) / 2) * scaleFactor);
}
//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];
UIImage* thumbnail = UIGraphicsGetImageFromCurrentImageContext();