Prevent Stretching image from uiimage in iphone sdk - iphone

Code snippet
self.newsImage = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,300,130)];
//set placeholder image or cell won't update when image is loaded
self.newsImage.image = [UIImage imageNamed:#"newsDetail.png"];
//load the image
self.newsImage.imageURL = [NSURL URLWithString:imageBig];
[imageBack addSubview:self.newsImage];
I have one image on 40*40 size but image view size 300*130. How to avoid stretching image.
I want center of the UIImageview.
Thanks in Advance !!!!

Just center the content:
self.newsImage.contentMode = UIViewContentModeCenter;

ou have to set CGSize as your image width and hight so 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;
}

Related

Objective c How to scale image view size (height) as per image size

In my application i have used and image view to display images getting from database
in data base images are having different sizes,
for now i added image view with frame (10, 10, 300, 220).
I need to resize the frames of image view as per image size, just like Aspect Fit.
I know Aspect fit can able to resize but it do in changing width as per height ratio,
But i need to increase the height as per width ratio
i need to have width always 300, fixed but need to changes in height
For ex :
if image size is 500x1000 i need to resize imageview as 300x600
if image size is 400x600 i need to resize imageview as 300x450
You can use the following code snippet which will meets your requirements
-(UIImage *)adjustImageSizeWhenCropping:(UIImage *)image
{
float actualHeight = image.size.height;
float actualWidth = image.size.width;
float ratio=300/actualWidth;
actualHeight = actualHeight*ratio;
CGRect rect = CGRectMake(0.0, 0.0, 300, actualHeight);
// UIGraphicsBeginImageContext(rect.size);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 1.0);
[image drawInRect:rect];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
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;
}

Resize UIImage and change the size of UIImageView

I have this UIImageView and I have the values of its max height and max width. What I want to achieve is that I want to take the image (with any aspect ratio and any resolution) and I want it to fit in the borders, so the picture does not exceed them, but it can shrink them as it wants. (marked red in the picture):
Right now the image fits the necessary size properly, but I have 2 worries:
1. The UIImageView is not equal the size of the resized image, thus leaving red background (and I don't want that)
2. If the image is smaller that the height of my UIImageView it is not resized to be smaller, it stays the same height.
Here's my code and I know its wrong:
UIImage *actualImage = [attachmentsArray lastObject];
UIImageView *attachmentImageNew = [[UIImageView alloc] initWithFrame:CGRectMake(5.5, 6.5, 245, 134)];
attachmentImageNew.image = actualImage;
attachmentImageNew.backgroundColor = [UIColor redColor];
attachmentImageNew.contentMode = UIViewContentModeScaleAspectFit;
So how do I dynamically change the size not only of the UIImageView.image, but of the whole UIImageView, thus making its size totally adjustable to its content. Any help would be much appreciated, thanks!
When you get the width and height of a resized image Get width of a resized image after UIViewContentModeScaleAspectFit, you can resize your imageView:
imageView.frame = CGRectMake(0, 0, resizedWidth, resizedHeight);
imageView.center = imageView.superview.center;
I haven't checked if it works, but I think all should be OK
- (UIImage *)image:(UIImage*)originalImage scaledToSize:(CGSize)size
{
//avoid redundant drawing
if (CGSizeEqualToSize(originalImage.size, size))
{
return originalImage;
}
//create drawing context
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);
//draw
[originalImage drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)];
//capture resultant image
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//return image
return image;
}
This is the Swift equivalent for Rajneesh071's answer, using extensions
UIImage {
func scaleToSize(aSize :CGSize) -> UIImage {
if (CGSizeEqualToSize(self.size, aSize)) {
return self
}
UIGraphicsBeginImageContextWithOptions(aSize, false, 0.0)
self.drawInRect(CGRectMake(0.0, 0.0, aSize.width, aSize.height))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
Usage:
let image = UIImage(named: "Icon")
item.icon = image?.scaleToSize(CGSize(width: 30.0, height: 30.0))
Use the category below and then apply border from Quartz into your image:
[yourimage.layer setBorderColor:[[UIColor whiteColor] CGColor]];
[yourimage.layer setBorderWidth:2];
The category:
UIImage+AutoScaleResize.h
#import <Foundation/Foundation.h>
#interface UIImage (AutoScaleResize)
- (UIImage *)imageByScalingAndCroppingForSize:(CGSize)targetSize;
#end
UIImage+AutoScaleResize.m
#import "UIImage+AutoScaleResize.h"
#implementation UIImage (AutoScaleResize)
- (UIImage *)imageByScalingAndCroppingForSize:(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; // scale to fit height
}
else
{
scaleFactor = heightFactor; // scale to fit width
}
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;
}
}
}
UIGraphicsBeginImageContext(targetSize); // this will crop
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");
}
//pop the context to get back to the default
UIGraphicsEndImageContext();
return newImage;
}
#end
If you have the size of the image, why don't you set the frame.size of the image view to be of this size?
EDIT----
Ok, so seeing your comment I propose this:
UIImageView *imageView;
//so let's say you're image view size is set to the maximum size you want
CGFloat maxWidth = imageView.frame.size.width;
CGFloat maxHeight = imageView.frame.size.height;
CGFloat viewRatio = maxWidth / maxHeight;
CGFloat imageRatio = image.size.height / image.size.width;
if (imageRatio > viewRatio) {
CGFloat imageViewHeight = round(maxWidth * imageRatio);
imageView.frame = CGRectMake(0, ceil((self.bounds.size.height - imageViewHeight) / 2.f), maxWidth, imageViewHeight);
}
else if (imageRatio < viewRatio) {
CGFloat imageViewWidth = roundf(maxHeight / imageRatio);
imageView.frame = CGRectMake(ceil((maxWidth - imageViewWidth) / 2.f), 0, imageViewWidth, maxHeight);
} else {
//your image view is already at the good size
}
This code will resize your image view to its image ratio, and also position the image view to the same centre as your "default" position.
PS: I hope you're setting imageView.layer.shouldRasterise = YES
and imageView.layer.rasterizationScale = [UIScreen mainScreen].scale;
if you're using CALayer shadow effect ;) It will greatly improve the performance of your UI.
I think what you want is a different content mode. Try using UIViewContentModeScaleToFill. This will scale the content to fit the size of ur UIImageView by changing the aspect ratio of the content if necessary.
Have a look to the content mode section on the official doc to get a better idea of the different content mode available (it is illustrated with images).
if([[SDWebImageManager sharedManager] diskImageExistsForURL:[NSURL URLWithString:#"URL STRING1"]])
{
NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:[NSURL URLWithString:#"URL STRING1"]];
UIImage *tempImage=[self imageWithImage:[[SDImageCache sharedImageCache] imageFromDiskCacheForKey:key] scaledToWidth:cell.imgview.bounds.size.width];
cell.imgview.image=tempImage;
}
else
{
[cell.imgview sd_setImageWithURL:[NSURL URLWithString:#"URL STRING1"] placeholderImage:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL)
{
UIImage *tempImage=[self imageWithImage:image scaledToWidth:cell.imgview.bounds.size.width];
cell.imgview.image=tempImage;
// [tableView beginUpdates];
// [tableView endUpdates];
}];
}

How to set frame UITableviewCell image size?

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;

iOS Resizing images for thumbs?

I am kinda new to handling images, there are many things that I do not know, so bear with me. Basically I take image with camera, and present it inside UIImageView, which is small view 60:80. Image is automatically resized to fit UIImageView, and everything looks fine.
My question is - Do I need to do some more image operations (is order to maximize efficency), or that's all?
Please use following code which will gives you better thumbnails
-(UIImage *)generatePhotoThumbnail:(UIImage *)image
{
CGSize size = image.size;
CGSize croppedSize;
CGFloat ratio = 120.0;
CGFloat offsetX = 0.0;
CGFloat offsetY = 0.0;
if (size.width > size.height) {
offsetX = (size.height - size.width) / 2;
croppedSize = CGSizeMake(size.height, size.height);
} else
{
offsetY = (size.width - size.height) / 2;
croppedSize = CGSizeMake(size.width, size.width);
}
CGRect clippedRect = CGRectMake(offsetX * -1, offsetY * -1, croppedSize.width, croppedSize.height);
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], clippedRect);
CGRect rect = CGRectMake(0.0, 0.0, ratio, ratio);
UIGraphicsBeginImageContext(rect.size);
[[UIImage imageWithCGImage:imageRef] drawInRect:rect];
UIImage *thumbnail = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRelease(imageRef);
return thumbnail;
}
Resize image function would be:
-(UIImage *)resizeImage:(CGSize)imgSize
UIGraphicsBeginImageContext(imgSize);
[image drawInRect:CGRectMake(0,0,imgSize.width,imgSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Save resized image in document directory with unique names. Later access thumbnail image from document directory.
If count of images is more than use lazy loading of images to display images.
If you are happy with the way the picture is displayed, then you don't need any additional code. Image views have no problems rescaling images for you and they are quite efficient at that, so don't worry about it.

How to clip image in scale in iPhone?

I have a large sized image (2048*2048px), this image is shown as 320*320 on iPhone screen. I want to do this:
In my APP, user can open large sized image(e.g. 2048*2048), the image is shown as 320*320 on iPhone screen, and there is rectangle over the image, user can move the rectangle anywhere within image on iPhone screen, e.g. rectangle(100, 100, 300, 200), then I want to clip the original sized image within the rectangle area in scale.
I tried many ways,
UIImageView *originalImageView = [[UIImage View alloc] initWithImage:originalImage]];
CGRect rect = CGRectMake(100, 100, 300, 200);
UIImage *cropImage = [UIImage imageWithCGImage:CGImageCreateWithImageInRect([originalImageView.image CGImage], rect)];
But I got the cropImage is just 300*200 sized image, not scale properly.
How about doing this, it will preserve the original image quality
CGSize bounds = CGSizeMake(320,320) // Considering image is shown in 320*320
CGRect rect = CGRectMake(100, 100, 220, 200); //rectangle area to be cropped
float widthFactor = rect.size.width * (originalImage.size.width/bounds.size.width);
float heightFactor = rect.size.height * (originalImage.size.height/bounds.size.height);
float factorX = rect.origin.x * (originalImage.size.width/bounds.size.width);
float factorY = rect.origin.y * (originalImage.size.height/bounds.size.height);
CGRect factoredRect = CGRectMake(factorX,factorY,widthFactor,heightFactor);
UIImage *cropImage = [UIImage imageWithCGImage:CGImageCreateWithImageInRect([originalImage CGImage], factoredRect)];
And most importantly if you want to crop image that imagePickerController returns, then this can be done by built in function as below,
imagePickerController.allowsEditing = YES;
Firstly resize image with size 320*320 using this method:
+(UIImage *)resizeImage:(UIImage *)image width:(float)width height:(float)height
{
CGSize newSize;
newSize.width = width;
newSize.height = height
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
Now set resized image in imageView
UIImage *resizeImage = [YourControllerName resizeImage:originalImage width:320 height:320];
UIImageView *originalImageView = [[UIImage View alloc] initWithImage:resizeImage]];
You can now crop
CGRect rect = CGRectMake(100, 100, 300, 200);
UIImage *cropImage = [UIImage imageWithCGImage:CGImageCreateWithImageInRect([originalImageView.image CGImage], rect)];
Why not calculate the scale factor (e.g. originalImageWidth/smallImageWidth)?
If the rectangle is (100,100,300,200) in your small image, you should clip your lage image at size (100*factor,100*factor,300*factor,200*factor).