I am working on new app, in which , i have different sizes of images. I have tried many times with different solution but could not find out the proper aspect ratio for images. I want to display images with a high quality too. There is some images have resolution 20*20 to 3456 * 4608 or it may be so high.
All images will be display without cropping ,but our app screen size is 300 * 370 pxls.
I was follow the following references :
1: Resize UIImage with aspect ratio?
2: UIViewContentModeScaleAspectFit
3: scale Image in an UIButton to AspectFit?
4:Resize UIImage with aspect ratio?
The code that I use for resizing images to an edge 1000px at most is this :
const int maxPhotoWidthOrHeight = 1000;
- (UIImage*)resizeImageWithImage:(UIImage*)image
{
CGFloat oldWidth = image.size.width;
CGFloat oldHeight = image.size.height;
NSLog(#"Old width %f , Old Height : %f ",oldWidth,oldHeight);
if (oldHeight > maxPhotoWidthOrHeight || oldWidth > maxPhotoWidthOrHeight) {//resize if necessary
CGFloat newHeight;
CGFloat newWidth;
if (oldHeight > oldWidth ) {
newHeight = maxPhotoWidthOrHeight;
newWidth = oldWidth * (newHeight/oldHeight);
}
else{
newWidth = maxPhotoWidthOrHeight;
newHeight = oldHeight * (newWidth/oldWidth);
}
CGSize newSize = CGSizeMake(newWidth, newHeight);
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSLog(#"New width %f , New Height : %f ",newImage.size.width,newImage.size.height);
return newImage;
}
else{//do not resize because both edges are less than 1000px
return image;
}
}
-- Please add you code example, otherwise its difficult to give any solution to your problem.
A solution found here is also How to scale a UIImageView proportionally?
imageView.contentMode = UIViewContentModeScaleAspectFit;
Related
I have one image of size 3264 × 2448 and an image view of size 768 × 1024. I want to get an image size equal to the view's size without losing image quality.
I googled for it; AspectFit not giving me proper output. I tried the following code:
- (UIImage *)imageByScalingProportionallyToSize: (CGSize)targetSize {
UIImage *sourceImage = self;
UIImage *newImage = nil;
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
if (CGSizeEqualToSize(imageSize, targetSize) == NO) {
CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;
if (widthFactor < heightFactor)
scaleFactor = widthFactor;
else
scaleFactor = heightFactor;
scaledWidth = width * scaleFactor;
scaledHeight = height * scaleFactor;
// center the image
if (widthFactor < heightFactor) {
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
} else if (widthFactor > heightFactor) {
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}
// this is actually the interesting part:
UIGraphicsBeginImageContext(targetSize);
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if(newImage == nil) NSLog(#"could not scale image");
return newImage ;
}
Please try below code :
+ (UIImage*)imageWithImage:(UIImage*)image
scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
specify your new size as (768,1024) and pass your original image, but make sure your height and width ratio of original image should be same as converted image ratio.
I used this article as reference for some of my projects included image resizing. UIImage+Resize category works pretty well except the significant performance hit until the resized version of image is created.
You may cache the resized version on disk to avoid resizing it again in future. Also I haven't tried yet but you can try resizing image in a background thread to avoid blocking the UI.
The dimensions of the input image isnt a multiple of your UIImageView's dimensions, and thats why aspectFit wont work here (will leave gaps on the sides most likely). if you use scaleToFill your image will warp because again your image dimensions are off. I think you will have to do something about the dimensions of one of these to preserve the image properly.
I use a small image size, such are 26*27, 15*28,... but the image is stretched and how to avoid and to set all image alignment are center.
You can set your image to center of image using UIViewContentModeCenter
Using code
imageView.contentMode=UIViewContentModeCenter;
using Nib
Use following method for to specify the height and width of image
+ (UIImage*)resizeImage:(UIImage*)image withWidth:(int)width withHeight:(int)height
{
CGSize newSize = CGSizeMake(width, height);
float widthRatio = newSize.width/image.size.width;
float heightRatio = newSize.height/image.size.height;
if(widthRatio > heightRatio)
{
newSize=CGSizeMake(image.size.width*heightRatio,image.size.height*heightRatio);
}
else
{
newSize=CGSizeMake(image.size.width*widthRatio,image.size.height*widthRatio);
}
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
This method return NewImage, with a specific size that you specify
i think u want :
imageView.contentMode = UIViewContentModeScaleAspectFill;
I have my UIImageView and I put an image into it that I resize like this:
UIImageView *attachmentImageNew = [[UIImageView alloc] initWithFrame:CGRectMake(5.5, 6.5, 245, 134)];
attachmentImageNew.image = actualImage;
attachmentImageNew.backgroundColor = [UIColor redColor];
attachmentImageNew.contentMode = UIViewContentModeScaleAspectFit;
I tried getting the width of the resized picture in my UIImageView by doing this:
NSLog(#"Size of pic is %f", attachmentImageNew.image.size.width);
But it actually returns me the width of the original picture. Any ideas on how do I get the frame of the picture that I see on screen?
EDIT: Here's how my UIImageView looks, red area is its backgroundColor
I don't know is there more clear solution, but this works:
float widthRatio = imageView.bounds.size.width / imageView.image.size.width;
float heightRatio = imageView.bounds.size.height / imageView.image.size.height;
float scale = MIN(widthRatio, heightRatio);
float imageWidth = scale * imageView.image.size.width;
float imageHeight = scale * imageView.image.size.height;
A solution in Swift:
let currentHeight = imageView.bounds.size.height
let currentWidth = imageView.bounds.size.width
let newWidth = UIScreen.mainScreen().bounds.width
let newHeight = (newWidth * currentHeight) / currentWidth
println(newHeight)
It has the reference of your original image, so always gives the same dimensions as of original image.
To get the dimensions of new image you have to check aspect ratio. I have derived a formula for my need using different images of different size using Preview that how it resizes image according to its aspect ratio.
According to Apple's Documentation for UIViewContentModeScaleAspectFit
It Scales the content (In your case actualImage) to fit the size of the view (In your case attachmentImageNew) by maintaining the
aspect ratio.
That means your image size ( after the scaling ) should be same as your UIImageView.
UPDATE :
One new Suggestion to you if you don't want to use UIViewContentModeScaleAspectFit and if you can fix the size of scaledImage then you can use below code to scale the image for fix newSize and then you can use the width to your code.
CGSize newSize = CGSizeMake(100.0,50.0);
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
in your case:
float yourScaledImageWitdh = attachmentImageNew.frame.size.height * attachmentImageNew.image.size.width / attachmentImageNew.image.size.height
NSLog(#"width of resized pic is %f", yourScaledImageWitdh);
but you should also check, before, the original image proportion vs the imageView proportion, my line of code is good just in case the red area is added horizontally, not in case your original image proportion is wider than the imageView frame proportion
For Swift 2, you can use this code snippet to align an aspectFitted image to the bottom of the screen (sampled from earlier answers to this question -> thanks to you, guys)
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenWidth = CGFloat(screenSize.width)
let screenHeight = CGFloat(screenSize.height)
imageView.frame = CGRectMake(0, screenHeight - (imageView.image?.size.height)! , screenWidth, (imageView.image?.size.height)!)
let newSize:CGSize = getScaledSizeOfImage(imageView.image!, toSize: self.view.frame.size)
imageView.frame = CGRectMake(0, screenHeight - (newSize.height) , screenWidth, newSize.height)
func getScaledSizeOfImage(image: UIImage, toSize: CGSize) -> CGSize
{
let widthRatio = toSize.width/image.size.width
let heightRatio = toSize.height/image.size.height
let scale = min(widthRatio, heightRatio)
let imageWidth = scale*image.size.width
let imageHeight = scale*image.size.height
return CGSizeMake(imageWidth, imageHeight)
}
I have used the below code from this link:
How to resize an UIImage while maintaining its Aspect Ratio
to resize an image to fixed size (100*100) by maintaing its aspect ratio. I have used AsyncImageView in my application to load the images using url's. You can get the AsyncImageView code from this link: nicklockwood / AsyncImageView
But still those images looks like squeezed. How can I solve this issue?
- (UIImage*) scaleImage:(UIImage*)image toSize:(CGSize)newSize {
CGSize scaledSize = newSize;
float scaleFactor = 1.0;
if( image.size.width > image.size.height ) {
scaleFactor = image.size.width / image.size.height;
scaledSize.width = newSize.width;
scaledSize.height = newSize.height / scaleFactor;
}
else {
scaleFactor = image.size.height / image.size.width;
scaledSize.height = newSize.height;
scaledSize.width = newSize.width / scaleFactor;
}
UIGraphicsBeginImageContextWithOptions( scaledSize, NO, 0.0 );
CGRect scaledImageRect = CGRectMake( 0.0, 0.0, scaledSize.width, scaledSize.height );
[image drawInRect:scaledImageRect];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}
This is how the images are being loaded in my application:
Why not use SDWebImage to get remote image?
Here is the link:https://github.com/rs/SDWebImage
I'm trying to get the image.size.h and image.size.w of the UIImage inside of an UIImageView with UIViewContentModeScaleAspectFit on.
I want the resized UIImage size, not the original image size.
Is it possible to get this value?
CGSize size=CGSizeMake(79, 84);//set the width and height
UIGraphicsBeginImageContext(size);
[image drawInRect:CGRectMake(0,0,size.width,size.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
//here is the scaled image which has been changed to the size specified
UIGraphicsEndImageContext();
This works for sure and don't forget to import QuartzCore FrameWork..
Have a Happy Coding (^_^)....
You can try calculate it by yourself:
//Your image
UIImage *image;
//Your imageView;
UIImageView *imageView;
int width, height;
float aspectRatio;
if (image.size.height > image.size.width)
{
height = imageView.frame.size.height;
aspectRatio = image.size.height / height;
width = image.size.width / aspectRatio;
}
else
{
width = imageView.frame.size.width;
aspectRatio = image.size.width / width;
height = image.size.height / aspectRatio;
}