A couple of thoughts:
You note that the image view is 320x568 points, but that the image itself is 3264x2448 pixels. The key observation is that the
UIGraphicsBeginImageContext...
functions are creating aUIImage
by rendering aUIImageView
and thus, the size of that resulting image will be linked to the size of thatUIKit
control and may bear little relation to the size of the actual originalUIImage
.In
getCroppedImageForView
, you are not considering thescale
of the device, notably not handling retina resolution (generating an image that is 320x568 pixels). Generally you'd do something like the following:- (UIImage *)imageForView:(UIView *)view { UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0); [view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
By using
UIGraphicsBeginImageContextWithOptions
with0
for the last option, it will reflect the scale of the device, and on retina screen it will generate image that is 640x1136 pixels.A minor simplification to
maskImageView
: By default, when adding a sublayer, it will use the same frame as the image view, so you can eliminate that setting of theframe
variable altogether, yielding:- (void)maskImageView:(UIImageView *)imageView { UIBezierPath *path = [self getPath]; CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = path.CGPath; shapeLayer.fillColor = [[UIColor whiteColor] CGColor]; shapeLayer.backgroundColor = [[UIColor clearColor] CGColor]; [imageView.layer setMask:shapeLayer]; }
In your
drawImage
, it is unnecessary to re-render the image. You already have theimage
. So just use thatUIImage
directly:- (void)writeToSavedPhotosAlbum:(UIImage*)image { UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); }
But if you really wanted to re-render the image, you'd use the same
UIGraphicsBeginImageContextWithOptions
syntax I illustrated in point 2, above, enjoying the extra resolution that a retina device provides.
While the above changes will render an image that is a little bigger, it's still considerably smaller than the original image's 3268x2448 pixels. If you really want to create a final image that is 3268x2448 pixels, there are two options that leap out at me:
One option is to make the image view the same size as the image (or more accurately, same size divided by the screen scale). You may want to put this image view on a scroll view and set the zoom scale appropriately.
The other option is to abandon UIKit for the rendering of the images, and shift to Core Image (a major refactoring of your code).
By the way, be aware that these large images will be much slower and consume a lot more memory. The internal, uncompressed size exceeds 30 mb each.