Related
I have image view on which i am displaying image selected from library. To display the fine quality picture i used to rescale the picture using below method. The image quality i am getting is perfect but i need to set the imageView frame according to the size of newly created image. but when i use newImage.size.width it is giving me the width of original image view. Please help me to set the image view frame according to displayed image size. Thanks in advance
-(UIImage *)scaleImage:(UIImage *)img toRectSize:(CGRect)screenRect
{
UIGraphicsBeginImageContext(screenRect.size);
float hfactor = img.size.width / screenRect.size.width;
float vfactor = img.size.height / screenRect.size.height;
float factor = MAX(hfactor, vfactor);
float newWidth = img.size.width / factor;
float newHeight = img.size.height / factor;
float leftOffset = (screenRect.size.width - newWidth) / 2;
float topOffset = (screenRect.size.height - newHeight) / 2;
CGRect newRect = CGRectMake(leftOffset, topOffset, newWidth, newHeight);
[img drawInRect:newRect blendMode:kCGBlendModePlusDarker alpha:1];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Try this code that I used for resizing image and you will get the new frame as well.The ratio seem to be fixed but you can change it as per your requirement.
-(UIImage*)ImageResize:(UIImage*)image
{
if(image==NULL)
{
return NULL;
}
else
{
float actualHeight = image.size.height;
float actualWidth = image.size.width;
float imgRatio = actualWidth/actualHeight;
float maxRatio = 130.0/160.0;
if(imgRatio!=maxRatio)
{
if(imgRatio < maxRatio)
{
imgRatio = 160.0 / actualHeight;
actualWidth = imgRatio * actualWidth;
actualHeight = 160.0;
}
else
{
imgRatio = 130.0 / actualWidth;
actualHeight = imgRatio * actualHeight;
actualWidth = 130.0;
}
}
CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
UIGraphicsBeginImageContext(rect.size);
[image drawInRect:rect];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
}
The below code can be used for specific image size that you can pass.
-(UIImage *)thumbnailWithImageWithoutScale:(UIImage *)image size:(CGSize)wantSize
{
UIImage * targetImage;
if (nil == image) {
targetImage = nil;
}else{
CGSize size = image.size;
CGRect rect;
if (wantSize.width/wantSize.height > size.width/size.height) {
rect.size.width = wantSize.height*size.width/size.height;
rect.size.height = wantSize.height;
rect.origin.x = (wantSize.width - rect.size.width)/2;
rect.origin.y = 0;
} else{
rect.size.width = wantSize.width;
rect.size.height = wantSize.width*size.height/size.width;
rect.origin.x = 0;
rect.origin.y = (wantSize.height - rect.size.height)/2;
}
UIGraphicsBeginImageContext(wantSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
UIRectFill(CGRectMake(0, 0, wantSize.width, wantSize.height));//clear background
[image drawInRect:rect];
targetImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
return targetImage;
}
Try this,
resizedImage = [self imageWithImage:originalImage scaledToSize:CGSizeMake(45,45)];
self.imageView.image = resizedImage;
- (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize
{
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Are you using Autolayout?
If yes you have to change width and height constraints of your image view not the frame (you can create outlets of them in the same way as you do for other controls).
For autolayout you can change frame in viewDidAppear method (in viewWillAppear or viewWillLoad it may not work.
Hi I am try to capture a view then save as an image into Photo Library , but I need create a custom resolution for captured image , here is my code but when app saves the images the resolution is low !
UIGraphicsBeginImageContextWithOptions(self.captureView.bounds.size, self.captureView.opaque, 0.0);
[self.captureView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * screenshot = UIGraphicsGetImageFromCurrentImageContext();
CGRect cropRect = CGRectMake(0 ,0 ,1435 ,1435);
CGImageRef imageRef = CGImageCreateWithImageInRect([screenshot CGImage], cropRect);
CGImageRelease(imageRef);
UIImageWriteToSavedPhotosAlbum(screenshot , nil, nil, nil);
UIGraphicsEndImageContext();
but the resolution in iPhone is : 320 x 320 and retina is : 640 x 640
I would be grateful if you help me to fix this issue .
Your code is pretty close. What you need to do is re-render the screenshot at the custom resolution. I modified your code to do this:
UIView* captureView = self.view;
/* Capture the screen shoot at native resolution */
UIGraphicsBeginImageContextWithOptions(captureView.bounds.size, captureView.opaque, 0.0);
[captureView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
/* Render the screen shot at custom resolution */
CGRect cropRect = CGRectMake(0 ,0 ,1435 ,1435);
UIGraphicsBeginImageContextWithOptions(cropRect.size, captureView.opaque, 1.0f);
[screenshot drawInRect:cropRect];
UIImage * customScreenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
/* Save to the photo album */
UIImageWriteToSavedPhotosAlbum(customScreenShot , nil, nil, nil);
Note that if capture view is not square then the image will be distorted. The saved image will always be square and 1435x1435 pixels.
have a look at this answer. The code includes rotation but nonetheless the questioner asked the same question: "How to get a […] image from an UIImageView at its full resolution?"
copied content (in case of deletion or whatever):
- (UIImage *)capturedView
{
float imageScale = sqrtf(powf(self.captureView.transform.a, 2.f) + powf(self.captureView.transform.c, 2.f));
CGFloat widthScale = self.captureView.bounds.size.width / self.captureView.image.size.width;
CGFloat heightScale = self.captureView.bounds.size.height / self.captureView.image.size.height;
float contentScale = MIN(widthScale, heightScale);
float effectiveScale = imageScale * contentScale;
CGSize captureSize = CGSizeMake(enclosingView.bounds.size.width / effectiveScale, enclosingView.bounds.size.height / effectiveScale);
NSLog(#"effectiveScale = %0.2f, captureSize = %#", effectiveScale, NSStringFromCGSize(captureSize));
UIGraphicsBeginImageContextWithOptions(captureSize, YES, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextScaleCTM(context, 1/effectiveScale, 1/effectiveScale);
[enclosingView.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
First get your image in UIImage object. Create your size what ever you want and use following..
UIImage *image = // you image;
CGSize size;
if ([[UIScreen mainScreen] respondsToSelector:#selector(displayLinkWithTarget:selector:)] &&
([UIScreen mainScreen].scale == 2.0)) {
// RETINA DISPLAY
size = CGSizeMake(640, 640);
}
else {
// Non Ratina device
size = CGSizeMake(320, 320);
}
UIGraphicsBeginImageContext(size);
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage *destImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Now you will get destImage with new resolution.
Hope this is what you are looking for :)
-(UIImage*)processImageRect:(UIImage*)image:(CGSize)sizeToForm {
// Draw image1
UIGraphicsBeginImageContext(CGSizeMake(sizeToForm.width, sizeToForm.height));
[image drawInRect:CGRectMake(0.0, 0.0, sizeToForm.width, sizeToForm.height)];
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
return resultingImage;
}
Go with this may solve your issue.
You can use that :
UIImageExtras.h
#interface UIImage (Extras)
-(UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize;
#end
UIImageExtras.m
#import "UIImageExtras.h"
#implementation UIImage (Extras)
- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize
{
//Image de base
UIImage *sourceImage = self;
//Image redimenssionnée
UIImage *newImage = nil;
//Taille de l'image de base
CGSize imageSize = sourceImage.size;
//Longueur et largeur
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
//Dimension désirée
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
//Echelle...
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
//Si taille des image est différentes on redimensionne de facon proportionnelle
if (CGSizeEqualToSize(imageSize, targetSize) == NO)
{
CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;
if (widthFactor > heightFactor)
scaleFactor = widthFactor; // scale to fit height
else
scaleFactor = heightFactor; // scale to fit width
scaledWidth = width * scaleFactor;
scaledHeight = height * scaleFactor;
//Centre l'image
if (widthFactor > heightFactor)
{
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
}
else if (widthFactor < heightFactor)
{
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}
UIGraphicsBeginImageContext(targetSize);
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
if(newImage == nil)
NSLog(#"could not scale image");
UIGraphicsEndImageContext();
return newImage;
}
#end
This worked for me. I tried with image that i got from Facebook SDK
http://pulkitgoyal.in/resizing-high-resolution-images-on-ios-without-memory-issues/
I think ALAssetRepresentation can help you.
CGSize sizePic = CGSizeMake(320, 460);
UIGraphicsBeginImageContext(sizePic);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *imagePic = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(imagePic, nil, nil, nil);
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>
+ (UIImage *)resizeImage:(UIImage *)image toResolution:(int)resolution {
NSData *imageData = UIImagePNGRepresentation(image);
CGImageSourceRef src = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
CFDictionaryRef options = (__bridge CFDictionaryRef) #{
(id) kCGImageSourceCreateThumbnailWithTransform : #YES,
(id) kCGImageSourceCreateThumbnailFromImageAlways : #YES,
(id) kCGImageSourceThumbnailMaxPixelSize : #(resolution)
};
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options);
CFRelease(src);
UIImage *img = [[UIImage alloc]initWithCGImage:thumbnail];
return img;
}
I am using different images and i want to include change color option. But i cant. Any body help me?
If you want to do image tinting, see UIImage+Tint.m in kballard/MGImageUtilities. If you want wholesale color replacement (e.g. treat an image as a silhouette and change the entire color to one flat color), see UIImage+Tint.m in mattgemmell/MGImageUtilities.
Its latest and most simple way to do it.
theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[theImageView setTintColor:[UIColor redColor]];
One way to accomplish this is to desaturate your image, and add a tint on top of that image with the color you desire.
Desaturate
-(UIImage *) getImageWithUnsaturatedPixelsOfImage:(UIImage *)image {
const int RED = 1, GREEN = 2, BLUE = 3;
CGRect imageRect = CGRectMake(0, 0, image.size.width*2, image.size.height*2);
int width = imageRect.size.width, height = imageRect.size.height;
uint32_t * pixels = (uint32_t *) malloc(width*height*sizeof(uint32_t));
memset(pixels, 0, width * height * sizeof(uint32_t));
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), [image CGImage]);
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
uint8_t * rgbaPixel = (uint8_t *) &pixels[y*width+x];
uint32_t gray = (0.3*rgbaPixel[RED]+0.59*rgbaPixel[GREEN]+0.11*rgbaPixel[BLUE]);
rgbaPixel[RED] = gray;
rgbaPixel[GREEN] = gray;
rgbaPixel[BLUE] = gray;
}
}
CGImageRef newImage = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
free(pixels);
UIImage * resultUIImage = [UIImage imageWithCGImage:newImage scale:2 orientation:0];
CGImageRelease(newImage);
return resultUIImage;
}
Overlay With Color
-(UIImage *) getImageWithTintedColor:(UIImage *)image withTint:(UIColor *)color withIntensity:(float)alpha {
CGSize size = image.size;
UIGraphicsBeginImageContextWithOptions(size, FALSE, 2);
CGContextRef context = UIGraphicsGetCurrentContext();
[image drawAtPoint:CGPointZero blendMode:kCGBlendModeNormal alpha:1.0];
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextSetBlendMode(context, kCGBlendModeOverlay);
CGContextSetAlpha(context, alpha);
CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(CGPointZero.x, CGPointZero.y, image.size.width, image.size.height));
UIImage * tintedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return tintedImage;
}
How-To
//For a UIImageView
yourImageView.image = [self getImageWithUnsaturatedPixelsOfImage:yourImageView.image];
yourImageView.image = [atom getImageWithTintedColor:yourImageView.image withTint:[UIColor redColor] withIntensity:0.7];
//For a UIImage
yourImage = [self getImageWithUnsaturatedPixelsOfImage:yourImage];
yourImage = [atom getImageWithTintedColor:yourImageView.image withTint:[UIColor redColor] withIntensity:0.7];
You can change the color of the tint to whatever you desire.
I have an application where I am displaying large images in a small space.
The images are quite large, but I am only displaying them in 100x100 pixel frames.
My app is responding slowly because of the size fo the images I am using.
To improve performance, how can I resize the images programmatically using Objective-C?
Please find the following code.
- (UIImage *)imageWithImage:(UIImage *)image convertToSize:(CGSize)size {
UIGraphicsBeginImageContext(size);
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage *destImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return destImage;
}
This code is for just change image scale not for resizing. You have to set CGSize as your image width and hight so the image will not stretch and it arrange at the middle.
- (UIImage *)imageWithImage:(UIImage *)image scaledToFillSize:(CGSize)size
{
CGFloat scale = MAX(size.width/image.size.width, size.height/image.size.height);
CGFloat width = image.size.width * scale;
CGFloat height = image.size.height * scale;
CGRect imageRect = CGRectMake((size.width - width)/2.0f,
(size.height - height)/2.0f,
width,
height);
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
[image drawInRect:imageRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
My favorite way to do this is with CGImageSourceCreateThumbnailAtIndex (in the ImageIO framework). The name is a bit misleading.
Here's an excerpt of some code from a recent app of mine.
CGFloat maxw = // whatever;
CGFloat maxh = // whatever;
CGImageSourceRef src = NULL;
if ([imageSource isKindOfClass:[NSURL class]])
src = CGImageSourceCreateWithURL((__bridge CFURLRef)imageSource, nil);
else if ([imageSource isKindOfClass:[NSData class]])
src = CGImageSourceCreateWithData((__bridge CFDataRef)imageSource, nil);
// if at double resolution, double the thumbnail size and use double-resolution image
CGFloat scale = 1;
if ([[UIScreen mainScreen] scale] > 1.0) {
scale = 2;
maxw *= 2;
maxh *= 2;
}
// load the image at the desired size
NSDictionary* d = #{
(id)kCGImageSourceShouldAllowFloat: (id)kCFBooleanTrue,
(id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue,
(id)kCGImageSourceCreateThumbnailFromImageAlways: (id)kCFBooleanTrue,
(id)kCGImageSourceThumbnailMaxPixelSize: #((int)(maxw > maxh ? maxw : maxh))
};
CGImageRef imref = CGImageSourceCreateThumbnailAtIndex(src, 0, (__bridge CFDictionaryRef)d);
if (NULL != src)
CFRelease(src);
UIImage* im = [UIImage imageWithCGImage:imref scale:scale orientation:UIImageOrientationUp];
if (NULL != imref)
CFRelease(imref);
If you are using a image on different sizes and resizing each time it will degrade your app performance. Solution is don't resize them just use button in place of imageview. and just set the image on button it will resize automatically and you will get great performance.
I was also resizing images while setting it on cell but my app got slow So I used Button in place of imageview (not resizing images programatically button is doing this job) and it is working perfectly fine.
-(UIImage *)scaleImage:(UIImage *)image toSize:. (CGSize)targetSize
{
//If scaleFactor is not touched, no scaling will occur
CGFloat scaleFactor = 1.0;
//Deciding which factor to use to scale the image (factor = targetSize / imageSize)
if (image.size.width > targetSize.width ||
image.size.height > targetSize.height || image.size.width == image.size.height)
if (!((scaleFactor = (targetSize.width /
image.size.width)) > (targetSize.height /
image.size.height))) //scale to fit width, or
scaleFactor = targetSize.height / image.size.height; // scale to fit heigth.
Since the code ran perfectly fine in iOS 4, for backwards compatibility I added a check for OS version and for anything below 5.0 the old code would work.
- (UIImage *)resizedImage:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)quality {
BOOL drawTransposed;
CGAffineTransform transform = CGAffineTransformIdentity;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0) {
// Apprently in iOS 5 the image is already correctly rotated, so we don't need to rotate it manually
drawTransposed = NO;
} else {
switch (self.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
drawTransposed = YES;
break;
default:
drawTransposed = NO;
}
transform = [self transformForOrientation:newSize];
}
return [self resizedImage:newSize
transform:transform
drawTransposed:drawTransposed
interpolationQuality:quality];
}
You can use this.
[m_Image.layer setMinificationFilter:kCAFilterTrilinear];
This thread is old, but it is what I pulled up when trying to solve this problem. Once the image is scaled it was not displaying well in my container even though I turned auto layout off. The easiest way for me to solve this for display in a table row, was to paint the image on a white background that had a fixed size.
Helper function
+(UIImage*)scaleMaintainAspectRatio:(UIImage*)sourceImage :(float)i_width :(float)i_height
{
float newHeight = 0.0;
float newWidth = 0.0;
float oldWidth = sourceImage.size.width;
float widthScaleFactor = i_width / oldWidth;
float oldHeight = sourceImage.size.height;
float heightScaleFactor = i_height / oldHeight;
if (heightScaleFactor > widthScaleFactor) {
newHeight = oldHeight * widthScaleFactor;
newWidth = sourceImage.size.width * widthScaleFactor;
} else {
newHeight = sourceImage.size.height * heightScaleFactor;
newWidth = oldWidth * heightScaleFactor;
}
// return image in white rect
float cxPad = i_width - newWidth;
float cyPad = i_height - newHeight;
if (cyPad > 0) {
cyPad = cyPad / 2.0;
}
if (cxPad > 0) {
cxPad = cxPad / 2.0;
}
CGSize size = CGSizeMake(i_width, i_height);
UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width, size.height), YES, 0.0);
[[UIColor whiteColor] setFill];
UIRectFill(CGRectMake(0, 0, size.width, size.height));
[sourceImage drawInRect:CGRectMake((int)cxPad, (int)cyPad, newWidth, newHeight)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
// will return scaled image at actual size, not in white rect
// UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
// [sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
// UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
// UIGraphicsEndImageContext();
// return newImage;
}
I called this like this from my table view cellForRowAtIndexPath
PFFile *childsPicture = [object objectForKey:#"picture"];
[childsPicture getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
if (!error) {
UIImage *largePicture = [UIImage imageWithData:imageData];
UIImage *scaledPicture = [Utility scaleMaintainAspectRatio:largePicture :70.0 :70.0 ];
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.image = scaledPicture;
[self.tableView reloadData];
}
}];
Hello from the end of 2018.
Solved with next solution (you need only last line, first & second are just for explanation):
NSURL *url = [NSURL URLWithString:response.json[0][#"photo_50"]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data scale:customScale];
'customScale' is scale which you want (>1 if image must be smaller, <1 if image must be bigger).
This c method will resize your image with cornerRadius "Without effecting image's quality" :
UIImage *Resize_Image(UIImage *iImage, CGFloat iSize, CGFloat icornerRadius) {
CGFloat scale = MAX(CGSizeMake(iSize ,iSize).width/iImage.size.width, CGSizeMake(iSize ,iSize).height/iImage.size.height);
CGFloat width = iImage.size.width * scale;
CGFloat height = iImage.size.height * scale;
CGRect imageRect = CGRectMake((CGSizeMake(iSize ,iSize).width - width)/2.0f,(CGSizeMake(iSize ,iSize).height - height)/2.0f,width,height);
UIGraphicsBeginImageContextWithOptions(CGSizeMake(iSize ,iSize), NO, 0);
[[UIBezierPath bezierPathWithRoundedRect:imageRect cornerRadius:icornerRadius] addClip];
[iImage drawInRect:imageRect];
UIImage *ResizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return ResizedImage;
}
This is how to use :
UIImage *ResizedImage = Resize_Image([UIImage imageNamed:#"image.png"], 64, 14.4);
I do not remember where i took the first 4 lines ..
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Resize UIImage with aspect ratio?
The following piece of code is resizing the image perfectly, but the problem is that it messes up the aspect ratio (resulting in a skewed image). Any pointers?
// Change image resolution (auto-resize to fit)
+ (UIImage *)scaleImage:(UIImage*)image toResolution:(int)resolution {
CGImageRef imgRef = [image CGImage];
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGRect bounds = CGRectMake(0, 0, width, height);
//if already at the minimum resolution, return the orginal image, otherwise scale
if (width <= resolution && height <= resolution) {
return image;
} else {
CGFloat ratio = width/height;
if (ratio > 1) {
bounds.size.width = resolution;
bounds.size.height = bounds.size.width / ratio;
} else {
bounds.size.height = resolution;
bounds.size.width = bounds.size.height * ratio;
}
}
UIGraphicsBeginImageContext(bounds.size);
[image drawInRect:CGRectMake(0.0, 0.0, bounds.size.width, bounds.size.height)];
UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageCopy;
}
I used this single line of code to create a new UIImage which is scaled. Set the scale and orientation params to achieve what you want. The first line of code just grabs the image.
// grab the original image
UIImage *originalImage = [UIImage imageNamed:#"myImage.png"];
// scaling set to 2.0 makes the image 1/2 the size.
UIImage *scaledImage =
[UIImage imageWithCGImage:[originalImage CGImage]
scale:(originalImage.scale * 2.0)
orientation:(originalImage.imageOrientation)];
That's ok not a big problem . thing is u got to find the proportional width and height
like if size is 2048.0 x 1360.0 which has to be resized to 320 x 480 resolution then the resulting image size should be 722.0 x 480.0
here is the formulae to do that . if w,h is original and x,y are resulting image.
w/h=x/y
=>
x=(w/h)*y;
submitting w=2048,h=1360,y=480 => x=722.0 ( here width>height. if height>width then consider x to be 320 and calculate y)
U can submit in this web page . ARC
Confused ? alright , here is category for UIImage which will do the thing for you.
#interface UIImage (UIImageFunctions)
- (UIImage *) scaleToSize: (CGSize)size;
- (UIImage *) scaleProportionalToSize: (CGSize)size;
#end
#implementation UIImage (UIImageFunctions)
- (UIImage *) scaleToSize: (CGSize)size
{
// Scalling selected image to targeted size
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
CGContextClearRect(context, CGRectMake(0, 0, size.width, size.height));
if(self.imageOrientation == UIImageOrientationRight)
{
CGContextRotateCTM(context, -M_PI_2);
CGContextTranslateCTM(context, -size.height, 0.0f);
CGContextDrawImage(context, CGRectMake(0, 0, size.height, size.width), self.CGImage);
}
else
CGContextDrawImage(context, CGRectMake(0, 0, size.width, size.height), self.CGImage);
CGImageRef scaledImage=CGBitmapContextCreateImage(context);
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
UIImage *image = [UIImage imageWithCGImage: scaledImage];
CGImageRelease(scaledImage);
return image;
}
- (UIImage *) scaleProportionalToSize: (CGSize)size1
{
if(self.size.width>self.size.height)
{
NSLog(#"LandScape");
size1=CGSizeMake((self.size.width/self.size.height)*size1.height,size1.height);
}
else
{
NSLog(#"Potrait");
size1=CGSizeMake(size1.width,(self.size.height/self.size.width)*size1.width);
}
return [self scaleToSize:size1];
}
#end
-- the following is appropriate call to do this if img is the UIImage instance.
img=[img scaleProportionalToSize:CGSizeMake(320, 480)];
This fixes the math to scale to the max size in both width and height rather than just one depending on the width and height of the original.
- (UIImage *) scaleProportionalToSize: (CGSize)size
{
float widthRatio = size.width/self.size.width;
float heightRatio = size.height/self.size.height;
if(widthRatio > heightRatio)
{
size=CGSizeMake(self.size.width*heightRatio,self.size.height*heightRatio);
} else {
size=CGSizeMake(self.size.width*widthRatio,self.size.height*widthRatio);
}
return [self scaleToSize:size];
}
This change worked for me:
// The size returned by CGImageGetWidth(imgRef) & CGImageGetHeight(imgRef) is incorrect as it doesn't respect the image orientation!
// CGImageRef imgRef = [image CGImage];
// CGFloat width = CGImageGetWidth(imgRef);
// CGFloat height = CGImageGetHeight(imgRef);
//
// This returns the actual width and height of the photo (and hence solves the problem
CGFloat width = image.size.width;
CGFloat height = image.size.height;
CGRect bounds = CGRectMake(0, 0, width, height);
Try to make the bounds's size integer.
#include <math.h>
....
if (ratio > 1) {
bounds.size.width = resolution;
bounds.size.height = round(bounds.size.width / ratio);
} else {
bounds.size.height = resolution;
bounds.size.width = round(bounds.size.height * ratio);
}