I made a custom overlay for a UIImagePickerController and it works great on an iPhone 5, but when tested on a 4 or 4S the overlay is too big.
How can I make my overlay fit properly on both screen sizes?
Here is my init method for my camera overlay.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.opaque = NO;
self.backgroundColor = [UIColor clearColor];
// load an image to show in the overlay
UIImage *constraints = [UIImage imageNamed:#"camera_overlay"];
UIImageView *constraintView = [[UIImageView alloc]initWithImage:constraints];
CGRect screenRect = [[UIScreen mainScreen]bounds];
constraintView.frame = CGRectMake(27, 10, screenRect.size.width - 50, screenRect.size.height - 80);
[self addSubview:constraintView];
_shootButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *shootImage = [UIImage imageNamed:#"cameraOverlayShootButton"];
UIImage *shootImageDown = [UIImage imageNamed:#"cameraOverlayShootDown"];
[_shootButton setBackgroundImage:shootImage forState:UIControlStateNormal];
[_shootButton setBackgroundImage:shootImageDown forState:UIControlStateHighlighted];
_shootButton.frame = CGRectMake(115, 465, 85, 85);
[self addSubview:_shootButton];
_cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *cancelImage = [UIImage imageNamed:#"cancelButton"];
[_cancelButton setBackgroundImage:cancelImage forState:UIControlStateNormal];
_cancelButton.frame = CGRectMake(265, 505, 25, 25);
[self addSubview:_cancelButton];
_flashButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *flashImage = [UIImage imageNamed:#"autoFlash"];
[_flashButton setBackgroundImage:flashImage forState:UIControlStateNormal];
_flashButton.frame = CGRectMake(8, 10, 40, 40);
[self addSubview:_flashButton];
}
return self;
}
Try this....
Step 1:
First create IBOutlet for UIImageview.
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = info[UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:YES completion:nil];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
OriginalImage=info[UIImagePickerControllerOriginalImage];
image = info[UIImagePickerControllerOriginalImage];
//----------------------------------------
imageview.image = image; //------------- additional method for custom image size
[self resizeImage];
//-----------------------------------------
if (_newMedia)
UIImageWriteToSavedPhotosAlbum(image,self,#selector(image:finishedSavingWithError:contextInfo:),nil);
}
else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
{
// Code here to support video if enabled
}
}
Step 2: Add this method to get image in common size in all devices
-(void)resizeImage
{
UIImage *resizeImage = imageview.image;
float width = 320;
float height = 320;
CGSize newSize = CGSizeMake(320,320);
UIGraphicsBeginImageContextWithOptions(newSize,NO,0.0);
CGRect rect = CGRectMake(0, 0, width, height);
float widthRatio = resizeImage.size.width / width;
float heightRatio = resizeImage.size.height / height;
float divisor = widthRatio > heightRatio ? widthRatio : heightRatio;
width = resizeImage.size.width / divisor;
height = resizeImage.size.height / divisor;
rect.size.width = width;
rect.size.height = height;
//indent in case of width or height difference
float offset = (width - height) / 2;
if (offset > 0) {
rect.origin.y = offset;
}
else {
rect.origin.x = -offset;
}
[resizeImage drawInRect: rect];
UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imageview.image = smallImage;
imageview.contentMode = UIViewContentModeScaleAspectFit;
}
Related
Is there an elegant way to only allow the user to take squarish photos with UIImagePickerController instead of the default rectangular ones? Something open source, maybe?
Here's the easiest way to do it (without reimplementing UIImagePickerController). First, use an overlay to make the camera field look square. Here's an example for 3.5" screens (you'd need to update it to work for iPhone 5):
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = source;
if (source == UIImagePickerControllerSourceTypeCamera) {
//Create camera overlay
CGRect f = imagePickerController.view.bounds;
f.size.height -= imagePickerController.navigationBar.bounds.size.height;
CGFloat barHeight = (f.size.height - f.size.width) / 2;
UIGraphicsBeginImageContext(f.size);
[[UIColor colorWithWhite:0 alpha:.5] set];
UIRectFillUsingBlendMode(CGRectMake(0, 0, f.size.width, barHeight), kCGBlendModeNormal);
UIRectFillUsingBlendMode(CGRectMake(0, f.size.height - barHeight, f.size.width, barHeight), kCGBlendModeNormal);
UIImage *overlayImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *overlayIV = [[UIImageView alloc] initWithFrame:f];
overlayIV.image = overlayImage;
[imagePickerController.cameraOverlayView addSubview:overlayIV];
}
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];
Then, after you get a picture back from the UIImagePickerController, crop it to a square with something like this:
//Crop the image to a square
CGSize imageSize = image.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
if (width != height) {
CGFloat newDimension = MIN(width, height);
CGFloat widthOffset = (width - newDimension) / 2;
CGFloat heightOffset = (height - newDimension) / 2;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(newDimension, newDimension), NO, 0.);
[image drawAtPoint:CGPointMake(-widthOffset, -heightOffset)
blendMode:kCGBlendModeCopy
alpha:1.];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
May be it will help you.
I'm using UIImagePickerController to choose an image from my Camera Roll and resizing it before uploading it to Parse.
I want to resize an image to certain size (let's say 750x1000) while retaining the aspect ratio of the original image. If necessary, I want to crop the image. I also want it to be easy to have different versions of the image (full size, thumbnail size). Right now I'm resizing only the height of the image. How can I achieve what I'm looking for?
Thanks.
NewProductViewController.h
#interface NewProductViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextFieldDelegate>
#property (nonatomic, strong) UIImage *image;
#property (nonatomic, strong) UIImagePickerController *imagePicker;
#property (nonatomic, weak) IBOutlet UIImageView *imageView;
- (UIImage *)imageWithImage:(UIImage *)sourceImage scaledToHeight:(float) i_height;
#end
NewProductViewController.m
- (IBAction)addImage:(id)sender {
self.imagePicker = [[UIImagePickerController alloc] init];
self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
self.imagePicker.delegate = self;
self.imagePicker.allowsEditing = NO;
[self presentViewController:self.imagePicker animated:NO completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
// A photo was selected
self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
if (self.imagePicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
// Save the image!
UIImageWriteToSavedPhotosAlbum(self.image, nil, nil, nil);
}
}
[self.imageView setImage:self.image];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (UIImage *)imageWithImage:(UIImage *)sourceImage scaledToHeight:(float) i_height {
float oldHeight = sourceImage.size.height;
float scaleFactor = i_height / oldHeight;
float newWidth = sourceImage.size.width* scaleFactor;
float newHeight = oldHeight * scaleFactor;
UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
[sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
- (IBAction)createProduct:(id)sender {
PFObject *newProduct = [PFObject objectWithClassName:#"Product"];
UIImage *newImage = [self imageWithImage:self.image scaledToHeight:1000.f];
UIImage *thumbnailImage = [self imageWithImage:self.image scaledToHeight:410.f];
NSData *imageData = UIImageJPEGRepresentation(newImage, 0.8f);
NSData *thumbnailData = UIImageJPEGRepresentation(thumbnailImage, 0.8f);
PFFile *imageFile = [PFFile fileWithName:#"image.jpg" data:imageData];
PFFile *thumbnailFile = [PFFile fileWithName:#"thumbnail.jpg" data:thumbnailData];
newProduct[#"imageFile"] = imageFile;
newProduct[#"thumbnailFile"] = thumbnailFile;
[newProduct setObject:[PFUser currentUser] forKey:#"user"];
}
Try this one, it crops source image proportionally and then scales it to necessary size:
- (UIImage *)imageWithImage:(UIImage *)sourceImage size:(CGSize)size {
CGSize newSize = CGSizeZero;
if ((sourceImage.size.width / size.width) < (sourceImage.size.height / size.height)) {
newSize = CGSizeMake(sourceImage.size.width, size.height * (sourceImage.size.width / size.width));
} else {
newSize = CGSizeMake(size.width * (sourceImage.size.height / size.height), sourceImage.size.height);
}
CGRect cropRect = CGRectZero;
cropRect.origin.x = (sourceImage.size.width - newSize.width) / 2.0f;
cropRect.origin.y = (sourceImage.size.height - newSize.height) / 2.0f;
cropRect.size = newSize;
CGImageRef croppedImageRef = CGImageCreateWithImageInRect([sourceImage CGImage], cropRect);
UIImage *croppedImage = [UIImage imageWithCGImage:croppedImageRef];
CGImageRelease(croppedImageRef);
UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width, size.height), NO, 0.0);
[croppedImage drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)];
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}
This code can help you:
UIImage *originalImage = [UIImage imageNamed:#"minions.png"];
CGSize destination = CGSizeMake(750, 1000);
UIGraphicsBeginImageContext(destination);
[originalImage drawInRect:CGRectMake(0,0,destination.width,destination.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *new = [[UIImageView alloc] initWithFrame:CGRectMake(40, 40, 750, 1000)];
new.image = newImage;
[self.view addSubview:New];
Let me know if it works for you :)
When scaling to precise width or height you may lose image resolution. So my solution is to crop to aspect ratio:
Swift 3
func cropImage(image: UIImage, to aspectRatio: CGFloat) -> UIImage {
let imageAspectRatio = image.size.height/image.size.width
var newSize = image.size
if imageAspectRatio > aspectRatio {
newSize.height = image.size.width * aspectRatio
} else if imageAspectRatio < aspectRatio {
newSize.width = image.size.height / aspectRatio
} else {
return image
}
let center = CGPoint(x: image.size.width/2, y: image.size.height/2)
let origin = CGPoint(x: center.x - newSize.width/2, y: center.y - newSize.height/2)
let cgCroppedImage = image.cgImage!.cropping(to: CGRect(origin: origin, size: CGSize(width: newSize.width, height: newSize.height)))!
let croppedImage = UIImage(cgImage: cgCroppedImage, scale: image.scale, orientation: image.imageOrientation)
return croppedImage
}
This is a simple method I created
-(UIImage *)getRescaledImage:(UIImage *)image{
int height = image.size.height;
int width = image.size.width;
int max = MOImageMaxHeightWidth;
float divideFactor = 0;
if(!(height > max) || !(width > max)){
return image;
}
if(height > width){
divideFactor = height/max;
}else{
divideFactor = width/max;
}
height = height/divideFactor;
width = width/divideFactor;
return [self imageWithImage:image scaledToSize:CGSizeMake(width, height)];
}
+ (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize {
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
MOImageMaxHeightWidth is a constant float value which you can give define for the max width/height. The aspect ratio of the image will be maintained. The variable divideFactor will take care of it and is self explanatory.
I have used below UIImage Categories. Hope this will work for you too.
https://github.com/mbcharbonneau/UIImage-Categories
CGFloat scale = .5f;
CGFloat maxSize = 1632 * 1224;
CGFloat currentSize = croppedImage.size.width * croppedImage.size.height;
if ((currentSize / 2) > maxSize) {
scale = maxSize / currentSize;
}
CGSize size = CGSizeMake(croppedImage.size.width * scale, croppedImage.size.height * scale);
__block UIImage *imageToSave = [croppedImage resizedImageWithContentMode:UIViewContentModeScaleAspectFill bounds:size interpolationQuality:kCGInterpolationLow];
I'm adding the overlay using pickerController's view and the uinavigationcontrollerdelegate as below.
-(void)navigationController:(UINavigationController *)navigationController didShowViewController: (UIViewController *)viewController animated:(BOOL)animated{
if ([navigationController.viewControllers count] == 3)
{
CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height;
UIView *plCropOverlay = [[[viewController.view.subviews objectAtIndex:1]subviews] objectAtIndex:0];
plCropOverlay.hidden = YES;
int position = 0;
if (screenHeight == 568)
{
position = 124;
}
else
{
position = 80;
}
CAShapeLayer *circleLayer = [CAShapeLayer layer];
UIBezierPath *path2 = [UIBezierPath bezierPathWithOvalInRect:
CGRectMake(0.0f, position, 320.0f, 320.0f)];
[path2 setUsesEvenOddFillRule:YES];
[circleLayer setPath:[path2 CGPath]];
[circleLayer setFillColor:[[UIColor clearColor] CGColor]];
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 320, screenHeight-72) cornerRadius:0];
[path appendPath:path2];
[path setUsesEvenOddFillRule:YES];
CAShapeLayer *fillLayer = [CAShapeLayer layer];
fillLayer.path = path.CGPath;
fillLayer.fillRule = kCAFillRuleEvenOdd;
fillLayer.fillColor = [UIColor blackColor].CGColor;
fillLayer.opacity = 0.8;
[viewController.view.layer addSublayer:fillLayer];
}
}
When the overlay defined above is added, I tend to get this view:
I can crop the image exactly to a square using a defined CGRect.
CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);
UIImage *cropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
How about approaching this problem where there is a circular overlay and imagePickers editing property is YES? I can zoom in and zoom out of the pic. How can i make use of the BezierPath here?
the short answer to your question addClip , but you mention you're a beginner, so here's all the steps from A to Z!!
Firstly, try this category, see if it helps. (If you're not familiar w/ categories have a google or just ask here in a comment.)
-(UIImage *)doMask
{
UIImage *maskImage = [UIImage imageNamed:#"yourMask.png"];
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef maskedImageRef = CGImageCreateWithMask([self CGImage], mask);
UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef];
CGImageRelease(mask);
CGImageRelease(maskedImageRef);
return maskedImage;
}
just create (I mean in photoshop) a png mask, and get familiar with that process.
I encourage you to master that process first...
Here are critical categories that will help...
-(UIImage *)becomeSquare
{
CGSize imageSize = self.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
UIImage *result = self;
if (width != height)
{
CGFloat newDimension = MIN(width, height);
CGFloat widthOffset = (width - newDimension) / 2;
CGFloat heightOffset = (height - newDimension) / 2;
UIGraphicsBeginImageContextWithOptions(
CGSizeMake(newDimension, newDimension), NO, 0. );
[result drawAtPoint:CGPointMake(-widthOffset, -heightOffset)
blendMode:kCGBlendModeCopy alpha:1. ];
result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
return result;
}
and a couple more ...
-(UIImage *)doScale
{
UIImage *result = self;
CGSize size = CGSizeMake(320,320);
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);
[result drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)];
result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
-(UIImage *)scaled640AnyShape
{
if ( self.size.height < 5.0 ) return nil;
if ( self.size.width < 5.0 ) return nil;
UIImage *result = self;
float widthShouldBe = 640.0;
float heightShouldBe = widthShouldBe * ( self.size.height / self.size.width );
CGSize size = CGSizeMake( widthShouldBe ,heightShouldBe );
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);
[result drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)];
result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
(obviously change the hard-coded output sizes as you wish.)
Note that your final result, will be achieved, by a combination in the appropriate order, such as:
yourImage = [yourImage doSquare];
yourImage = [yourImage doMask];
once you've got that working ...
Then ....
for LITERALLY what you ask, there are many example codes about .. e.g., what about https://stackoverflow.com/a/13870097/294884
As you can see, you fundamentally...
UIGraphicsBeginImageContextWithOptions(...);
UIBezierPath * path = [UIBezierPath
bezierPathWithRoundedRect:imageRect cornerRadius:10.f];
[path addClip];
[yourImage drawInRect:imageRect];
... then ... UIGraphicsGetImageFromCurrentImageContext();
.. see the extensive code above for how to save it and so on.
You just have to get the zoom right with the scaling examples above.
Also note this, when you are changing the "area cropped"... https://stackoverflow.com/a/17884863/294884
here's an example of that critical technique...
-(UIImage *)squareAndSmall
{
// genius credits: https://stackoverflow.com/a/17884863/294884
CGSize finalsize = CGSizeMake(640,640);
CGFloat scale = MAX(
finalsize.width/self.size.width,
finalsize.height/self.size.height);
CGFloat width = self.size.width * scale;
CGFloat height = self.size.height * scale;
// for example, the central area....
CGRect imageRect = CGRectMake(
(finalsize.width - width)/2.0f,
(finalsize.height - height)/2.0f,
width, height);
// or, the top area... CGRect imageRect = CGRectMake( 0, 0, width, height);
UIGraphicsBeginImageContextWithOptions(finalsize, NO, 0);
[self drawInRect:imageRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Hope it all helps!
Found this blog post entry very interesting, neat and simple to follow by Nimit Parekh.
Following code is copy/paste into your “viewcontroller.h” file:
#import <UIKit/UIKit.h>
#interface UIImagePickerDemoViewController : UIViewController< UIImagePickerControllerDelegate, UINavigationControllerDelegate>
#property(nonatomic,retain) UIImagePickerController *imgPicker;
#property(nonatomic,retain) IBOutlet UIImageView *image_view;
//- (UIImage*)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)rect;
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage;
#end
Following Code copy/paste into “viewcontroller.m” file:
// Following method is use for the mask the image.
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
return [UIImage imageWithCGImage:masked];
}
// Following method is use for Cropping the image for a perticular size.
- (UIImage*)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)rect
{
UIGraphicsBeginImageContext(rect.size);
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(currentContext, 0.0, rect.size.height);
CGContextScaleCTM(currentContext, 1.0, -1.0);
CGRect clippedRect = CGRectMake(0, 0, rect.size.width, rect.size.height);
CGContextClipToRect( currentContext, clippedRect);
CGRect drawRect = CGRectMake(rect.origin.x * -1,rect.origin.y * -1,imageToCrop.size.width,imageToCrop.size.height);
CGContextDrawImage(currentContext, drawRect, imageToCrop.CGImage);
CGContextScaleCTM(currentContext, 1.0, -1.0);
UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return cropped;
}
// Calling the method of maskimage.
//=============================Camera Enable(display)============================================
-(IBAction)next:(id)sender{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
self.imgPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
[self presentModalViewController:self.imgPicker animated:YES];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[picker dismissModalViewControllerAnimated:YES];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];
UIImage *img = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
self.image_view.image=[self maskImage:img withMask:[UIImage imageNamed:#"frame.png"]];
}
//===============================================================================================
// Calling the method of cropping the image.
//=============================Camera Enable(display)============================================
-(IBAction)next:(id)sender{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
self.imgPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
[self presentModalViewController:self.imgPicker animated:YES];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[picker dismissModalViewControllerAnimated:YES];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];
UIImage *img = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
self.image_view.image = [self imageByCropping:img toRect:CGRectMake(0, 0, 420, 40)];
}
//===============================================================================================
Output:
Grab the source code here.
Im having exactly the same profile image picker controller as your. Here is my code from delegate. I don't think you need everything but you can find some useful information here
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = info[UIImagePickerControllerMediaType];
if([mediaType isEqualToString:(NSString *) kUTTypeImage]) {
UIImage *image = info[UIImagePickerControllerOriginalImage];
UIImage *editedImage = (UIImage *) [info objectForKey:UIImagePickerControllerEditedImage];
CGRect croppingRect = [info[UIImagePickerControllerCropRect] CGRectValue];
if (editedImage) {
image = editedImage;
} else {
CGFloat smaller = 1;
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")) {
smaller = 0.9;
}
CGFloat width = MIN(image.size.width * smaller, image.size.height * (smaller * 0.95));
croppingRect = CGRectMake(0 + (image.size.width - width) / 2,
0 + (image.size.height - width) / 2,
width, width);
}
UIImage *finalImage = nil;
if (editedImage) {
finalImage = [UIImage image:editedImage byScalingAndCroppingForSize:kCroppedImageSize];
} else {
finalImage = [UIImage image:image byScalingAndCroppingForSize:kCroppedImageSize];
}
if ([self.imagePickerDelegate respondsToSelector:#selector(profileImagePicker:didSelectImage:)]) {
[self.imagePickerDelegate profileImagePicker:self didSelectImage:finalImage];
} else {
NSAssert(nil, #"Delegate should confirm ProfileImagePickerControllerDelegate protocol");
}
} else if ([mediaType isEqualToString:(NSString *) kUTTypeVideo]) {
NSAssert(nil, #"Movie is not supported");
}
}
I use two different methods to crop the center square out of this image. One works, one doesn't. My question is why.
Here are the two results:
Clearly, the left is buggy and the right works.
The image you see on the left uses only CGImageCreateWithImageInRect to
select the region of the image, where the rect is scaled by the ratio of the
original image dimensions to those of the view's dimensions. Why doesn't this method work?
The image you see on the right translates the image and then selects the region
of interest with the origin at 0,0 using CGImageCreateWithImageInRect
Here's the code that draws both images:
- (UIImage *)cropImage:(UIImage *)original inRect:(CGRect)rect {
CGFloat heightScale = original.size.height / self.view.frame.size.height;
CGFloat widthScale = original.size.width / self.view.frame.size.width;
CGRect scaledRect = CGRectMake(rect.origin.x * widthScale, rect.origin.y * heightScale, rect.size.width * widthScale, rect.size.height * heightScale);
UIGraphicsBeginImageContextWithOptions(original.size, YES, 1.0);
[original drawAtPoint:CGPointMake(-scaledRect.origin.x, -scaledRect.origin.y)];
UIImage *translatedImage = UIGraphicsGetImageFromCurrentImageContext();
CGRect finalRect = CGRectMake(0, 0, scaledRect.size.width, scaledRect.size.height);
CGImageRef imageRefForRightImage = CGImageCreateWithImageInRect([translatedImage CGImage], finalRect);
CGImageRef imageRefForLeftImage = CGImageCreateWithImageInRect([original CGImage], scaledRect);
UIImage *croppedRightImage = [UIImage imageWithCGImage:imageRefForRightImage];
UIImage *croppedLeftImage = [UIImage imageWithCGImage:imageRefForLeftImage];
CGImageRelease(imageRefForRightImage);
CGImageRelease(imageRefForLeftImage);
UIImageView *colorImageView = [[UIImageView alloc] initWithFrame:self.view.frame];
colorImageView.backgroundColor = [UIColor purpleColor];
[self.view addSubview:colorImageView];
CGRect rectLeft = CGRectMake(0, 0, 160, 160);
CGRect rectRight = CGRectMake(160, 0, 160, 160);
UIImageView *croppedImageViewLeft = [[UIImageView alloc] initWithFrame:rectLeft];
UIImageView *croppedImageViewRight = [[UIImageView alloc] initWithFrame:rectRight];
croppedImageViewLeft.image = croppedLeftImage;
croppedImageViewRight.image = croppedRightImage;
croppedImageViewLeft.contentMode = UIViewContentModeScaleAspectFit;
croppedImageViewRight.contentMode = UIViewContentModeScaleAspectFit;
[self.view addSubview:croppedImageViewLeft];
[self.view addSubview:croppedImageViewRight];
croppedImageViewRight.image = croppedRightImage;
croppedImageViewLeft.image = croppedLeftImage;
return croppedRightImage;
}
I'm uring iCarossel with SDWebImage. Everything works just fine but when the image size is too big it just goes out of the screen.
Following is the snippet where image view is generated
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
[((UIImageView *)view) setImageWithURL:[NSURL URLWithString:#"http://www.pizzatower.com/img/icons/Pizza-icon.png"]];
// [((UIImageView *)view) setImageWithURL:[NSURL URLWithString:#"http://www.rivercitypizza.com/PepperoniPizza-full.jpg"]];
view.contentMode = UIViewContentModeCenter;
view.frame = CGRectMake(0, 0, 256, 256);
label = [[UILabel alloc] initWithFrame:view.bounds];
label.backgroundColor = [UIColor clearColor];
label.font = [label.font fontWithSize:10];
label.tag = 1;
[view addSubview:label];
I tried changint the frame attribute but nothing changes. Could someone point me out how to resize the image and keep it within the size of the screen?
If you use view.contentMode = UIViewContentModeScaleAspectFit; your image will be scaled to fit inside the frame.
Set Your UIImageView ContentMode
YourImageView.contentMode=UIViewContentModeScaleToFill;
Use this code
Write this line in your code.
UIImage *ResizeImage=[self resizeImage:YourMainUIImage resizeSize:CGSizeMake(100,100)];
Add add this method in your ViewController
-(UIImage *) resizeImage:(UIImage *)orginalImage resizeSize:(CGSize)size
{
CGFloat actualHeight = orginalImage.size.height;
CGFloat actualWidth = orginalImage.size.width;
float oldRatio = actualWidth/actualHeight;
float newRatio = size.width/size.height;
if(oldRatio < newRatio)
{
oldRatio = size.height/actualHeight;
actualWidth = oldRatio * actualWidth;
actualHeight = size.height;
}
else
{
oldRatio = size.width/actualWidth;
actualHeight = oldRatio * actualHeight;
actualWidth = size.width;
}
CGRect rect = CGRectMake(0.0,0.0,actualWidth,actualHeight);
UIGraphicsBeginImageContext(rect.size);
[orginalImage drawInRect:rect];
orginalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return orginalImage;
}
Try with this :
UIImage *resizedImage = [self imageWithImage:self.image scaledToSize:CGSizeMake(768, 1024)];
- (UIImage *)imageWithImage:(UIImage *)imagee scaledToSize:(CGSize)newSize {
//UIGraphicsBeginImageContext(newSize);
// In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
// Pass 1.0 to force exact pixel size.
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[imagee drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}