Resize UIImageView in iOS - ios

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;
}

Related

iOS UISegmentedControl with image overlaps by tint color

I have some problem with UISegmentedControl with image. When I put image with text on it in segment tintcolor paints my image and the text.
Can any help with it?
setting up UIImage in Segment
UIImage *tmp = [UIImage imageNamed:#"UISegmentedControl-active"];
UIImage *imageWithText = [UIImage imageFromImage:tmp string:#"20" color:[UIColor whiteColor]];
[self.segmentedControl setImage:imageWithText forSegmentAtIndex:0];
imageFromImage code:
+ (id) imageFromImage:(UIImage*)image string:(NSString*)string color:(UIColor*)color
{
UIFont *font = [UIFont systemFontOfSize:16.0];
CGSize expectedTextSize = [string sizeWithAttributes:#{NSFontAttributeName: font}];
int width = image.size.width + 5;
int height = MAX(expectedTextSize.height, image.size.width);
CGSize size = CGSizeMake((float)width, (float)height);
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, color.CGColor);
int fontTopPosition = (height - expectedTextSize.height) / 2;
CGPoint textPoint = CGPointMake(width + 5, fontTopPosition);
// Images upside down so flip them
//CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, size.height);
//CGContextConcatCTM(context, flipVertical);
CGContextDrawImage(context, (CGRect){ {0, (height - image.size.height) / 2}, {image.size.width, image.size.height} }, [image CGImage]);
[string drawAtPoint:textPoint withAttributes:#{NSFontAttributeName: font}];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Image goes blue(default tintcolor).
Anyway, if anyone know how to do segmented control with circular(not rounded) segments(buttons), offer your solution.

Move UIImage inside UIImageView

I have an UIImageView (red squares) that will display a UIImage that must be scaled (I can receive images greater or smaller that the UIImageView). After scaling it, the showed part of the UIImage is the center of it.
What I need is to show the part of the image in the blue squares, how can I archive it?
I'm only able to get the image size (height and width), but it display the original size, when it's supposed to be the scaled one.
self.viewIm = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 120, 80)];
self.viewIm.backgroundColor = [UIColor greenColor];
self.viewIm.layer.borderColor = [UIColor redColor].CGColor;
self.viewIm.layer.borderWidth = 5.0;
UIImage *im = [UIImage imageNamed:#"benjen"];
self.viewIm.image = im;
self.viewIm.contentMode = UIViewContentModeScaleAspectFill;
// self.viewim.clipsToBounds = YES;
[self.view addSubview:self.viewIm];
To do what you're trying to do, I'd recommend looking into CALayer's contentsRect property.
Since seeing your answer, I've been trying to work out the proper solution for a while, but the mathematics escapes me because contentsRect:'s x and y parameters seem sort of mysterious... But here's some code that may point you in the right direction...
float imageAspect = self.imageView.image.size.width/self.imageView.image.size.height;
float imageViewAspect = self.imageView.frame.size.width/self.imageView.frame.size.height;
if (imageAspect > imageViewAspect) {
float scaledImageWidth = self.imageView.frame.size.height * imageAspect;
float offsetWidth = -((scaledImageWidth-self.imageView.frame.size.width)/2);
self.imageView.layer.contentsRect = CGRectMake(offsetWidth/self.imageView.frame.size.width, 0.0, 1.0, 1.0);
} else if (imageAspect < imageViewAspect) {
float scaledImageHeight = self.imageView.frame.size.width * imageAspect;
float offsetHeight = ((scaledImageHeight-self.imageView.frame.size.height)/2);
self.imageView.layer.contentsRect = CGRectMake(0.0, offsetHeight/self.imageView.frame.size.height, 1.0, 1.0);
}
Try something like this:
CGRect cropRect = CGRectMake(0,0,200,200);
CGImageRef imageRef = CGImageCreateWithImageInRect([ImageToCrop CGImage],cropRect);
UIImage *image = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
I found a very good approximation on this answer. In that, the category resize the image, and use the center point to crop after that. I adapt it to crop using (0,0) as origin point. As I don't really need a category, I use it as a single method.
- (UIImage *)imageByScalingAndCropping:(UIImage *)image forSize:(CGSize)targetSize {
UIImage *sourceImage = image;
UIImage *newImage = nil;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetSize.width;
CGFloat scaledHeight = targetSize.height;
if (CGSizeEqualToSize(image.size, targetSize) == NO) {
if ((targetSize.width / image.size.width) > (targetSize.height / image.size.height)) {
scaleFactor = targetSize.width / image.size.width; // scale to fit height
} else {
scaleFactor = targetSize.height / image.size.height; // scale to fit width
}
scaledWidth = image.size.width * scaleFactor;
scaledHeight = image.size.height * scaleFactor;
}
UIGraphicsBeginImageContext(targetSize); // this will crop
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = CGPointZero;
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;
}
And my call is something like this:
self.viewIm = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 120, 80)];
self.viewIm.image = [self imageByScalingAndCropping:[UIImage imageNamed:#"benjen"] forSize:CGSizeMake(120, 80)];
[self.view addSubview:self.viewIm];
I've spent some time on this and finally created a Swift 3.2 solution (based on one of my answers on another thread, as well as one of the answers above). This code only allows for Y translation of the image, but with some tweaks anyone should be able to add horizontal translation as well ;)
let yOffset: CGFloat = 20
myImageView.contentMode = .scaleAspectFill
//scale image to fit the imageView's width (maintaining aspect ratio), but allow control over the image's Y position
UIGraphicsBeginImageContextWithOptions(myImageView.frame.size, myImageView.isOpaque, 0.0)
let ratio = myImage.size.width / myImage.size.height
let newHeight = myImageView.frame.width / ratio
let rect = CGRect(x: 0, y: -yOffset, width: myImageView.frame.width, height: newHeight)
myImage.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext() ?? myImage
UIGraphicsEndImageContext()
//set the new image
myImageView.image = newImage
Now you can adjust how far down or up you need the image to be by changing the yOffset.

Retrieving UIImage from UIImageView sized accordingly

How may I retrieve the image from imageView sized as it is displayed (given the content mode), and not as it is according to native properties?
Code:
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, WID, WID)];
imageView.center = CGPointMake(point.x, point.y + Y_OFFSET);
imageView.image = [UIImage imageNamed:#"img"];
imageView.contentMode = UIViewContentModeScaleAspectFit;
You have to draw the image again then save it.
// Image frame size
CGSize size = imageView.bounds.size;
// Grab a new CGContext
UIGraphicsBeginImageContextWithOptions(size, false, 0.0);
// Draw the image
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
// Grab the new image
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
The above code draws the image in the frame, stretched to the bounds. If you want any other modes of how it is drawn, you have to calculate them yourself and put the desired stuff in the "Draw the image" line of code.
For example, for aspect fit, check out this algorithm:
- (CGRect) aspectFittedRect:(CGSize)inSize max:(CGRect)maxRect {
float originalAspectRatio = inSize.width / inSize.height;
float maxAspectRatio = maxRect.size.width / maxRect.size.height;
CGRect newRect = maxRect;
if (originalAspectRatio > maxAspectRatio) { // scale by width
newRect.size.height = maxRect.size.height * inSize.height / inSize.width;
newRect.origin.y += (maxRect.size.height - newRect.size.height)/2.0;
} else {
newRect.size.width = maxRect.size.height * inSize.width / inSize.height;
newRect.origin.x += (maxRect.size.width - newRect.size.width)/2.0;
}
return CGRectIntegral(newRect);
}
Just pass in imageView.image.size as inSize and imageView.bounds as maxRect.
Source:
http://iphonedevsdk.com/forum/iphone-sdk-development-advanced-discussion/15001-aspect-fit-algorithm.html

Cropping an image

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;
}

UIImagePickerController fit camera overlay on different screen sizes

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;
}

Resources