This question already has answers here:
Resize UIImage by keeping Aspect ratio and width
(19 answers)
Closed 7 years ago.
I'm using the UIImagePickerController to chose an image from my library and uploading it to Parse. How can I resize my image's height only? I want the image to keep it's aspect ratio but I don't want the height to be taller than 1000px.
Right now I'm resizing both the width and height to a fixed number with this code:
ViewController.h
- (UIImage *)resizeImage:(UIImage *)image toWidth:(float)width andHeight:(float)height;
ViewController.h
- (UIImage *)resizeImage:(UIImage *)image toWidth:(float)width andHeight:(float)height {
CGSize newSize = CGSizeMake(width, height);
CGRect newRectangle = CGRectMake(0, 0, width, height);
UIGraphicsBeginImageContext(newSize);
[self.image drawInRect:newRectangle];
UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resizedImage;
}
- (IBAction)createProduct:(id)sender {
UIImage *newImage = [self resizeImage:self.image toWidth:750.0f andHeight:1000.0f];
NSData *imageData = UIImagePNGRepresentation(newImage);
PFFile *imageFile = [PFFile fileWithName:#"image.jpg" data:imageData];
}
Thanks.
+(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;
}
You will have to get the aspect ration of the original dimensions and multiply that with your new height
Pseudocode
if (height > 1000){
aspectRatio = width/height;
height = 1000;
width = height * aspectRatio
}
- (IBAction)createProduct:(id)sender {
UIImage *newImage;
if (self.image.size.height > 1000){
CGFloat aspectRatio = self.image.size.width/self.image.size.height;
CGFloat height = 1000;
CGFloat width = height * aspectRatio;
newImage = [self resizeImage:self.image toWidth:width andHeight:height];
} else {
newImage = self.image;
}
NSData *imageData = UIImagePNGRepresentation(newImage);
PFFile *imageFile = [PFFile fileWithName:#"image.jpg" data:imageData];
}
Related
I am using the following crop method to crop a uiimage that's sitting in a UIImageView which is then sitting in a UIScrollView.
-(UIImage *)cropImage:(UIImage *)image
{
float scale = 1.0f/_scrollView.zoomScale;
NSLog(#"Oh and heres that zoomScale: %f", _scrollView.zoomScale);
CGRect visibleRect;
visibleRect.origin.x = _scrollView.contentOffset.x * scale;
visibleRect.origin.y = _scrollView.contentOffset.y * scale;
visibleRect.size.width = _scrollView.bounds.size.width * scale;
visibleRect.size.height = _scrollView.bounds.size.height * scale;
NSLog(#"Oh and here's that CGRect: %f", visibleRect.origin.x);
NSLog(#"Oh and here's that CGRect: %f", visibleRect.origin.y);
NSLog(#"Oh and here's that CGRect: %f", visibleRect.size.width);
NSLog(#"Oh and here's that CGRect: %f", visibleRect.size.height);
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], visibleRect);
UIImage *croppedImage = [[UIImage alloc] initWithCGImage:imageRef];
CGImageRelease(imageRef);
return croppedImage;
}
I need the image to be cropped to a CGSize of (321,115). Upon cropping the image and seeing the print results, I can see that visibleRect is (0,0,321,115) - what it is supposed to be, the croppedImage UIImage then has width:321 and height:115. for some reason however the image appears to be zoomed in entirely too far (the method cropped a smaller portion of the original image to a size of 321x115).
Why is this method not correctly cropping my image?
-As a side note: When I call this method, I am calling like so _croppedImage = [self cropImage:_imageView.image]; which sets a UIImage property of a custom UIView class to the cropped image.
Please try this function. It may help you.
Parameters:
UIImage
CGSize (321,115) or any size
// crop image - image will crop from full image
- (UIImage *)cropImageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
double ratio;
double delta;
CGPoint offset;
//make a new square size, that is the resized imaged width
CGSize sz = CGSizeMake(newSize.width, newSize.width);
//figure out if the picture is landscape or portrait, then
//calculate scale factor and offset
if (image.size.width > image.size.height) {
ratio = newSize.width / image.size.width;
delta = (ratio*image.size.width - ratio*image.size.height);
offset = CGPointMake(delta/2, 0);
}
else {
ratio = newSize.width / image.size.height;
delta = (ratio*image.size.height - ratio*image.size.width);
offset = CGPointMake(0, delta/2);
}
//make the final clipping rect based on the calculated values
CGRect clipRect = CGRectMake(-offset.x,
-offset.y,
(ratio * image.size.width) + delta,
(ratio * image.size.height) + delta);
//start a new context, with scale factor 0.0 so retina displays get
//high quality image
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(sz, YES, 0.0);
} else {
UIGraphicsBeginImageContext(sz);
}
UIRectClip(clipRect);
[image drawInRect:clipRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
To crop only selected portion of image
Please check this link
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];
In my app I import an image from either the camera or the photo library using a UIImagePickerController. Than I save the imported image to the app documents directory. This all works fine, however I would like to save the image cropped as a square(like on instagram) instead of it's original size.The square should be the size of either the width of the image or the height of it(depending on which is the smaller one). I figured that maybe a CGRect would be useful here, but I have no idea how to crop a CGRect out of an image..I have looked at countless tutorials but none of them seemed to work or they were all too complicated..
-(UIImage *)squareImage:(UIImage *)image
{
if (image.size.width>=image.size.height)
{
image=[self imageWithImage:image scaledToHeight:100];
}
else
{
image=[self imageWithImage:image scaledToWidth:100];
}
return image;
}
-(UIImage*)imageWithImage:(UIImage*)sourceImage scaledToWidth:(float)width
{
float oldWidth = sourceImage.size.width;
float scaleFactor = width / oldWidth;
float newHeight = sourceImage.size.height * scaleFactor;
float newWidth = oldWidth * scaleFactor;
UIGraphicsBeginImageContext(CGSizeMake(newWidth, newWidth));
[sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
-(UIImage*)imageWithImage:(UIImage*)sourceImage scaledToHeight:(float)height
{
float oldHeight = sourceImage.size.height;
float scaleFactor = height / oldHeight;
float newWidth = sourceImage.size.width * scaleFactor;
float newHeight = oldHeight * scaleFactor;
UIGraphicsBeginImageContext(CGSizeMake(newHeight, newHeight));
[sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
above method will help you to scale image proportionately and scaling image in square..for rotation you can search on google.
I need help resizing a UIImage.
For example: I'm displaying a lot images in a UICollection View, but the size of those images is 2 to 4 MB. I need compress or resize those images.
I found this: How to compress/resize image on iPhone OS SDK before uploading to a server? but I don't understand how to implement it.
Not quite sure if you want to resize or compress or both.
Below is the code for just compression :
Use JPEG Compression in two simple steps:
1) Convert UIImage to NSData
UIImage *rainyImage =[UImage imageNamed:#"rainy.jpg"];
NSData *imgData= UIImageJPEGRepresentation(rainyImage,0.1 /*compressionQuality*/);
this is lossy compression and image size is reduced.
2) Convert back to UIImage;
UIImage *image=[UIImage imageWithData:imgData];
For scaling you can use answer provided by Matteo Gobbi. But scaling might not be a the best alternative. You would rather prefer to have a thumbnail of the actual image by compression because scaling might make look your image bad on a retina display device.
I wrote this function to scale an image:
- (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)newSize {
CGSize actSize = image.size;
float scale = actSize.width/actSize.height;
if (scale < 1) {
newSize.height = newSize.width/scale;
} else {
newSize.width = newSize.height*scale;
}
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
The use is easy, for example:
[self scaleImage:yourUIImage toSize:CGMakeSize(300,300)];
lowResImage = [UIImage imageWithData:UIImageJPEGRepresentation(highResImage, quality)];
-(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;
}
//this image you can add it to imageview.....
In my app, I am taking picture with camera and displaying it in 320*320 UIView. But as the image resolution is more than that of UIView its kinda look squeezed. Is there any way I can resize that image?
Here's how you can resize the image while preserving its aspect ratio. The code below is from a category for UIImage:
+ (UIImage*)imageWithImage:(UIImage *)image
scaledToSize:(CGSize)newSize
{
float heightToWidthRatio = image.size.height / image.size.width;
float scaleFactor = 1;
if(heightToWidthRatio > 0) {
scaleFactor = newSize.height / image.size.height;
} else {
scaleFactor = newSize.width / image.size.width;
}
CGSize newSize2 = newSize;
newSize2.width = image.size.width * scaleFactor;
newSize2.height = image.size.height * scaleFactor;
UIGraphicsBeginImageContext(newSize2);
[image drawInRect:CGRectMake(0,0,newSize2.width,newSize2.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
I do this, but first I enable the photo picker to editable so it is default 1:1 aspect, like so:
imgPicker.allowsImageEditing = YES; //I think this is what you're really looking for
then I resize the image using this method:
-(UIImage*)resizeImage:(UIImage*)image{
CGSize newSize = CGSizeMake(480.0, 480.0);
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}