UIImage from object c to swift and image size bad - swift

i've a PNG image that i would insert into my navigation title.
In Object C i've
UIImage *image = [UIImage imageNamed:#"logo_up.png"];
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:image];
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
CGFloat screenHeight = screenSize.height;
it works very well and my image was in high quality
Then i create a similar APP in swift, using the same image, and write this code
self.navigationItem.titleView = UIImageView(image: UIImage(named: "icons/logo_up.png"))
self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor()
self.navigationController?.navigationBar.frame.size.width = 320
self.navigationController?.navigationBar.frame.size.height = 44
it print my image but with very poor quality.
I create different image with different size but nothing change. Every image in this APP have poor quality.
I use PNG and JPG extension.

Try to play with the content mode of your UIImageView. You are changing the frame of the UINavigationBar in your Swift example, the image can be reduced in quality by doing this.
let imageView = UIImageView(image: UIImage(named: "icons/logo_up.png"))
imageView.contentMode = .ScaleAspectFit //change contentMode
self.navigationItem.titleView = imageView
self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor() self.navigationController?.navigationBar.frame.size.width = 320
self.navigationController?.navigationBar.frame.size.height = 44

Related

Get width of a resized image after UIViewContentModeScaleAspectFit

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

How to manage UIImageView content mode?

I have an UIImageView with some fixed rect size. But my images are not fixed in size. I want to display images according to UIImageView's rect size. Whether image is big or large in resolution it must be in fixed display according to UIImageView's size. I am confused in using below assets.
UIViewContentModeScaleToFill,
UIViewContentModeScaleAspectFit,
UIViewContentModeScaleAspectFill,
UIViewContentModeRedraw
What to set in autoresize mask ?
How do they behave ?
Please try this code, Hope it will work for you.
set UIImageView contentMode to UIViewContentModeScaleAspectFill as below :
imageView.contentMode = UIViewContentModeScaleAspectFill;
set autoresizingMask of UIImageView as below :
imageView.autoresizingMask =
( UIViewAutoresizingFlexibleBottomMargin
| UIViewAutoresizingFlexibleHeight
| UIViewAutoresizingFlexibleLeftMargin
| UIViewAutoresizingFlexibleRightMargin
| UIViewAutoresizingFlexibleTopMargin
| UIViewAutoresizingFlexibleWidth );
You just need these two lines:
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.layer.clipsToBounds = YES; // Must do this or else image will overflow
Here a solution for swift:
let imageView = UIImageView(image: UIImage(named: "backgroundImage"))
imageView.frame = tableView.frame
imageView.contentMode = .ScaleAspectFill
tableView.backgroundView = imageView
If you want to make your UIImageView size according to ratio ,then you must set it's mode to UIViewContentModeScaleAspectFit
yourimage.contentMode=UIViewContentModeScaleAspectFit;
let me know it is working or not!!!
Happy Coding.
In swift you set content mode as well
var newImgThumb : UIImageView
newImgThumb = UIImageView(frame:CGRectMake(0, 0, 100, 70))
newImgThumb.contentMode = .ScaleAspectFit
Worth noting that swift 3 has changed as following
.ScaleAspectFit to scaleAspectFit
.ScaleAspectFill to .scaleAspectFill
Hope this helpful for you
CGImageRef imageRef = CGImageCreateWithImageInRect([largeImage CGImage], cropRect);
image = [UIImage imageWithCGImage:imageRef]];
CGImageRelease(imageRef);

Image is not fit to the frame of UIImageView

I am creating the UIImageView using interface Builder. Its frame size is (320,67).
I want to display the image on the imageView. I am getting the image from the web. The problem is that the image get from web is stretched to display on the imageview...
Here my code
NSData *imageData=[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://www.isco.com/webproductimages/appBnr/bnr1.jpg"]];
imageView.image = [UIImage imageWithData:imageData];
Can anyone tel me that how to display the image fit to display on imageView????
Either use
imageView.contentMode = UIViewContentModeScaleAspectFill;
or
imageView.contentMode = UIViewContentModeScaleAspectFit;
The first one will fill the frame, possibly cutting off parts of your image. The second one will show the entire image, possibly leaving areas of the frame open.
For Swift :
imageView.contentMode = UIViewContentMode.ScaleAspectFit
For Objective-C :
imageView.contentMode = UIViewContentModeScaleAspectFit
ScaleAspectFit option is use to scale the content to fit the size of the view by maintaining the aspect ratio. Any remaining areas of the view’s bounds is transparent.
Refer Apple docs for details.
I ended up resizing the image after the image was scaled according to it's aspect ratio.
let widthRatio = ImageView.bounds.size.width / (captureImageView.image?.size.width)!
let heightRatio = ImageView.bounds.size.height / (captureImageView.image?.size.height)!
let scale = min(widthRatio, heightRatio)
let imageWidth = scale * (ImageView.image?.size.width)!
let imageHeight = scale * (ImageView.image?.size.height)!
ImageView.frame = CGRect(x: 0, y: 0, width: imageWidth, height: imageHeight)
Try this code.
imView.contentMode = UIViewContentModeScaleAspectFit;

How to stretch Image to fill the Label Width set in Background in UILabel?

I have simple View based application. I had taken only UILabel on it.
Following is my code in viewDidLoad:
lblBack.textColor = [UIColor blueColor];
UIImage *img = [UIImage imageNamed:#"cn3.png"];
lblBack.backgroundColor = [UIColor colorWithPatternImage:img];
lblBack.text = #"Hello World!!!...";
// UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
//
// CGRect rect = CGRectMake(0, 0, lblBack.frame.size.width, lblBack.frame.size.height);
// [imgView setFrame:rect];
// NSLog(#"Rect : %#",NSStringFromCGRect(rect));
// [img drawInRect:rect];
// imgView.contentMode = UIViewContentModeScaleAspectFill;
// imgView.contentMode = UIViewContentModeScaleAspectFit;
// imgView.contentMode = UIViewContentModeScaleToFill;
// [lblBack addSubview:imgView];
Comments shows some of the things that i have tried. I am getting following output:
In this one image is repeated 3 times. But I want that image should be stretched to fill the Label width.
I have referred some of the previous links that shows me to add Image in background and use clearColor for UILabel. Also seen example of Adding custom view in Background. But all this I dont want to use unless I dont have other solutions...
I just want to perform all things on UILabel only.... no other control except UIImage or UIImageView i want to use..
Dhiren try this code :
UIImage *img = [UIImage imageNamed:#"cab.png"];
CGSize imgSize = testLabel.frame.size;
UIGraphicsBeginImageContext( imgSize );
[img drawInRect:CGRectMake(0,0,imgSize.width,imgSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
testLabel.backgroundColor = [UIColor colorWithPatternImage:newImage];
I have tested this code.
Porting over Maulik's answer to Swift 2.2, you get the following code:
var img: UIImage = UIImage(named: "cabImage")!
var imgSize: CGSize = testLabel.frame.size
UIGraphicsBeginImageContext(imgSize)
img.drawInRect(CGRectMake(0, 0, imgSize.width, imgSize.height))
var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
testLabel.backgroundColor = UIColor(patternImage: newImage)
Personally tested to be working!

How to fill background image of an UIView

I have an UIView and I set a background image in this way:
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"sfond-appz.png"]];
My problem is that back-image is not centered inside the view, but it's replayed some times to fill all the view. Is there a way to center image inside uiview and scretch to have screen size?
Note: I can't use UIImageView for background cause I have a scrollview.
You need to process the image beforehand, to make a centered and stretched image.
Try this:
UIGraphicsBeginImageContext(self.view.frame.size);
[[UIImage imageNamed:#"image.png"] drawInRect:self.view.bounds];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.view.backgroundColor = [UIColor colorWithPatternImage:image];
For Swift use this...
UIGraphicsBeginImageContext(self.view.frame.size)
UIImage(named: "ImageName.png")?.draw(in: self.view.bounds)
if let image = UIGraphicsGetImageFromCurrentImageContext(){
UIGraphicsEndImageContext()
self.view.backgroundColor = UIColor(patternImage: image)
}else{
UIGraphicsEndImageContext()
debugPrint("Image not available")
}
The colorWithPattern: method is really for generating patterns from images. Thus, the customization you require is most likely not possible, nor is it meant to be.
Indeed you need to use a UIImageView to center and scale an image. The fact that you have a UIScrollView does not prevent this:
Make self.view a generic view, then add both the UIImageView and the UIScrollView as subviews. Make sure all is wired up correctly in Interface Builder, and make the background color of the scroll view transparent.
This is IMHO the simplest and most flexible design for future changes.
Repeat:
UIImage *img = [UIImage imageNamed:#"bg.png"];
view.backgroundColor = [UIColor colorWithPatternImage:img];
Stretched
UIImage *img = [UIImage imageNamed:#"bg.png"];
view.layer.contents = img.CGImage;
Correct way to do in Swift 4,
If your frame as screen size is correct then put anywhere otherwise,
important to write this in viewDidLayoutSubviews because we can get actual frame in viewDidLayoutSubviews
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
UIGraphicsBeginImageContext(view.frame.size)
UIImage(named: "myImage")?.draw(in: self.view.bounds)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
view.backgroundColor = UIColor.init(patternImage: image!)
}
For Swift 2.1 use this...
UIGraphicsBeginImageContext(self.view.frame.size)
UIImage(named: "Cyan.jpg")?.drawInRect(self.view.bounds)
let image: UIImage! = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.view.backgroundColor = UIColor(patternImage: image)
You can use UIGraphicsBeginImageContext method to set the size of image same that of view.
Syntax : void UIGraphicsBeginImageContext(CGSize size);
#define IMAGE(imageName) (UIImage *)[UIImage imageWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:imageName ofType:IMAGE_TYPE_PNG]]
UIGraphicsBeginImageContext(self.view.frame.size);
[[UIImage imageNamed:#“MyImage.png"] drawInRect:self.view.bounds];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.view.backgroundColor = [UIColor colorWithPatternImage:IMAGE(#"mainBg")];
For Swift 3.0 use the following code:
UIGraphicsBeginImageContext(self.view.frame.size)
UIImage(named: "bg.png")?.drawAsPattern(in: self.view.bounds)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
self.view.backgroundColor = UIColor(patternImage: image)
The marked answer is fine, but it makes the image stretched.
In my case I had a small tile image that I wanted repeat not stretch.
And the following code was the best way for me to solve the black background issue:
UIImage *tileImage = [UIImage imageNamed:#"myTileImage"];
UIColor *color = [UIColor colorWithPatternImage:tileImage];
UIView *backgroundView = [[UIView alloc] initWithFrame:self.view.frame];
[backgroundView setBackgroundColor:color];
//backgroundView.alpha = 0.1; //use this if you want to fade it away.
[self.view addSubview:backgroundView];
[self.view sendSubviewToBack:backgroundView];
Swift 4 Solution :
#IBInspectable var backgroundImage: UIImage? {
didSet {
UIGraphicsBeginImageContext(self.frame.size)
backgroundImage?.draw(in: self.bounds)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
if let image = image{
self.backgroundColor = UIColor(patternImage: image)
}
}
}