Resize UIImageView based on image with respect to UIImageViewWidth - uiimageview

I have a UIImageView that is the width of the entire screen and the height is 400 pixels.
The end result I am looking for is that every single image has the exact same width (the screen width) and the height is adjusted to accommodate this while keeping its aspect ratio.
So if an image is 400 pixels wide, it needs to reduce to 320 pixels wide, and the height of the image view should adjust and become SHORTER to keep the ratio.
If an image is 240 pixels wide, it needs to increase its width to 320 and adjust the hight to be TALLER to keep the ratio.
I have been looking through many posts that all seem to just point to setting the content mode to aspect fit, but this does nothing like what I am looking for.
Any help would be great, thanks!

So it looks like shortly after I posted it, I checked storyboard, and for some reason the code was not overwriting the storyboard.
If I change it to Aspect Fit in storyboard, it actually functions the way it is supposed to.
::face palm::

You just need to set the content mode property to Aspect Fit in your imageview.

UIImage *originalImage = [UIImage imageNamed:#"xxx.png"];
double width = originalImage.size.width;
double height = originalImage.size.height;
double apectRatio = width/height;
//You can mention your own width like 320.0
double newHeight = [[UIScreen mainScreen] bounds].size.width/ apectRatio;
self.img.frame = CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, newHeight);
self.img.center = self.view.center;
self.img.image = originalImage;

func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage {
let size = image.size
let widthRatio = targetSize.width / image.size.width
let heightRatio = targetSize.height / image.size.height
// Figure out what our orientation is, and use that to form the rectangle
var newSize: CGSize
if(widthRatio > heightRatio) {
newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
} else {
newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
}
// This is the rect that we've calculated out and this is what is actually used below
let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
// Actually do the resizing to the rect using the ImageContext stuff
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
Now get the resized image from the original image, as I done it like:
let image = UIImage(named: "YOUR IMAGE NAME")
let newHeight = (image?.size.height/image?.size.width) * YOUR_UIIMAGE_VIEW_WIDTH
let newSize = CGSize(width: YOUR_UIIMAGE_VIEW_WIDTH, height: newHeight)
let newResizedImage = resizeImage(image: image, targetSize: newSize)
Hope, this will help.

Related

UISlider Thumb Image gets pixelated even if I use .svg file

Why is my custom thumb image gets blurry or pixelated even if I use svg file. When I use the image on a button, it works fine. Please help. Here's my code
func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage? {
let size = image.size
let widthRatio = targetSize.width / size.width
let heightRatio = targetSize.height / size.height
// Figure out what our orientation is, and use that to form the rectangle
var newSize: CGSize
if(widthRatio > heightRatio) {
newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
} else {
newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
}
// This is the rect that we've calculated out and this is what is actually used below
let rect = CGRect(origin: .zero, size: newSize)
// Actually do the resizing to the rect using the ImageContext stuff
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
and then I call it in my viewDidLoad():
let resized = resizeImage(image: (UIImage(named: "add_svg")!), targetSize: CGSize(width: 100.0, height: 100.0))
slider.setThumbImage(resized, for: .normal)
See below photo. the upper image is a button, the below image (slightly blurred) is the thumb image of uislider. Thanks in advance!
enter image description here

Resize image in NSTextView to fit

I have NSAttributedString objects with embedded images. These are being presented in NSTextViews. In iOS, I was able to resize the bounds of NSTextAttachment, and this makes the image fit.
extension NSTextAttachment {
func setImageWidth(width: CGFloat, range: NSRange) {
var thisImage = image
if thisImage == nil {
thisImage = imageForBounds(bounds, textContainer: nil, characterIndex: range.location)
}
if thisImage != nil {
let ratio = thisImage!.size.height / thisImage!.size.width
bounds = CGRectMake(bounds.origin.x, bounds.origin.y, width, ratio * width)
print("New Bounds: \(bounds)")
}
}
}
This code also runs on OSX, but it does not actually resize the image. Below you can see, there is a box of the correct size around the image, but the actual image overflows the box.
I have also followed the following guide: Implementing Rich Text with Images on OS X and iOS. This moves the code to subclasses, but has the same effect.
Any suggestions? Is there something besides NSTextAttachment.bounds that I should be adjusting?
UPDATE
I found that modifying the size component of NSImage works! However, it is now showing all my images upside, but at the correct size. :(
Solved!
extension NSImage {
func resizeToFit(containerWidth: CGFloat) {
var scaleFactor : CGFloat = 1.0
let currentWidth = self.size.width
let currentHeight = self.size.height
if currentWidth > containerWidth {
scaleFactor = (containerWidth * 0.9) / currentWidth
}
let newWidth = currentWidth * scaleFactor
let newHeight = currentHeight * scaleFactor
self.size = NSSize(width: newWidth, height: newHeight)
print("Size: \(size)")
}
}
As I mentioned in the update, you need to change the NSImage.size. The flip was coming from one of the subclasses I had left in there from the link in the question. Once I went back to the main classes, it works!

Add size (constraints) to SpriteNode

I'm looking for a way to add height and width constraints to a SpriteNode.
let firstObject = SKSpriteNode(imageNamed: "card1")
override func didMoveToView(view: SKView) {
firstObject.position = CGPoint(x: size.width * 0.5, y: size.height * 0.5)
addChild(firstObject)
}
This is my code at the moment - it shows the image but it is way to big, so now I want to do something like this;
firstObject.addConstraints(height and width)
But I can't seem to find the answer anywhere.
You set the size using its size property:
let width: CGFloat = 100
let height: CGFloat = 100
firstObject.size = CGSizeMake(width, height)

Confused about NSImageView scaling

I'm trying to display a simple NSImageView with it's image centered without scaling it like this:
Just like iOS does when you set an UIView's contentMode = UIViewContentModeCenter
So I tried all NSImageScaling values, this is what I get when I chose NSScaleNone
I really don't understand what's going on :-/
You can manually generate the image of the correct size and content, and set it to be the image of the NSImageView so that NSImageView doesn't need to do anything.
NSImage *newImg = [self resizeImage:sourceImage size:newSize];
[aNSImageView setImage:newImg];
The following function resizes an image to fit the new size, keeping the aspect ratio intact. If the image is smaller than the new size, it is scaled up and filled with the new frame. If the image is larger than the new size, it is downsized, and filled with the new frame
- (NSImage*) resizeImage:(NSImage*)sourceImage size:(NSSize)size{
NSRect targetFrame = NSMakeRect(0, 0, size.width, size.height);
NSImage* targetImage = [[NSImage alloc] initWithSize:size];
NSSize sourceSize = [sourceImage size];
float ratioH = size.height/ sourceSize.height;
float ratioW = size.width / sourceSize.width;
NSRect cropRect = NSZeroRect;
if (ratioH >= ratioW) {
cropRect.size.width = floor (size.width / ratioH);
cropRect.size.height = sourceSize.height;
} else {
cropRect.size.width = sourceSize.width;
cropRect.size.height = floor(size.height / ratioW);
}
cropRect.origin.x = floor( (sourceSize.width - cropRect.size.width)/2 );
cropRect.origin.y = floor( (sourceSize.height - cropRect.size.height)/2 );
[targetImage lockFocus];
[sourceImage drawInRect:targetFrame
fromRect:cropRect //portion of source image to draw
operation:NSCompositeCopy //compositing operation
fraction:1.0 //alpha (transparency) value
respectFlipped:YES //coordinate system
hints:#{NSImageHintInterpolation:
[NSNumber numberWithInt:NSImageInterpolationLow]}];
[targetImage unlockFocus];
return targetImage;}
Here's an awesome category for NSImage: NSImage+ContentMode
It allows content modes like in iOS, works great.
Set image scaling property to NSImageScaleAxesIndependently which will scale image to fill rectangle.This will not preserve aspect ratio.
Swift version of #Shagru's answer (without the hints)
func resizeImage(_ sourceImage:NSImage, size:CGSize) -> NSImage
{
let targetFrame = CGRect(origin: CGPoint.zero, size: size);
let targetImage = NSImage.init(size: size)
let sourceSize = sourceImage.size
let ratioH = size.height / sourceSize.height;
let ratioW = size.width / sourceSize.width;
var cropRect = CGRect.zero;
if (ratioH >= ratioW) {
cropRect.size.width = floor (size.width / ratioH);
cropRect.size.height = sourceSize.height;
} else {
cropRect.size.width = sourceSize.width;
cropRect.size.height = floor(size.height / ratioW);
}
cropRect.origin.x = floor( (sourceSize.width - cropRect.size.width)/2 );
cropRect.origin.y = floor( (sourceSize.height - cropRect.size.height)/2 );
targetImage.lockFocus()
sourceImage.draw(in: targetFrame, from: cropRect, operation: .copy, fraction: 1.0, respectFlipped: true, hints: nil )
targetImage.unlockFocus()
return targetImage;
}

CVPixelBufferRef to NSImage

How can I convert a CVPixelBufferRef to an NSImage or CGImageRef? I need to be able to display the contents of the pixel buffer in a Core Animation Layer.
To convert the buffer to an image, you need to first convert the buffer to an CIImage, which then can be converted to an NSImage.
let ciImage = CIImage(cvImageBuffer: pixelBuffer)
let context = CIContext(options: nil)
From here you can go to both GCImage and NSImage:
let width = CVPixelBufferGetWidth(pixelBuffer)
let height = CVPixelBufferGetHeight(pixelBuffer)
let cgImage = context.createCGImage(ciImage, from: CGRect(x: 0, y: 0, width: width, height: height))
let nsImage = NSImage(cgImage: cgImage, size: CGSize(width: width, height: height))

Resources