Resizing image for icons for iPad2 - swift - swift

Simple code for resizing image i.e. for navbar (source link) for png image with native res: 722x1028
let imageView = UIImageView(frame: CGRectMake(0, 0, 0, 60))
imageView.image = UIImage(named: "girl")
imageView.contentMode = UIViewContentMode.ScaleAspectFit
self.navigationItem.titleView = imageView
And I get on iPad2:
I can manually render desired image by changing code:
let imageView = UIImageView(frame: CGRectMake(0, 0, 0, 60))
imageView.image = imageWithImage(UIImage(named: "girl")!, scaledToSize: CGSizeMake(42,60))
self.navigationItem.titleView = imageView
func imageWithImage(image:UIImage, scaledToSize newSize:CGSize) -> UIImage{
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0);
image.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
But this is rather expensive solution.
Is there native library or simple swift solution to make png image automatically resized with good quality?

If you have hardcoded size 42x60 points for all devices, the best solution would be to provide pre-rendered image in that size. This is friendly to the battery and allows tweaking the image in a high quality editor before adding to the app: Resizing from 1000 pixels to 60 pixels is a bit drastic and will lead to loss of detail.
If that's not possible (i.e. image is dynamically loaded from the internet etc.), I would start my research with CIImage and CIFilter(name: "CILanczosScaleTransform") which provides very good interpolation quality, possibly followed by CISharpenLuminance if the loss of detail is too high.

Related

Trying to save merged images but nothing works correctly

I have looked at every example I can find in previous questions and nothing works. I am merging two images by copying a cropped image to pasteboard and then pasting it in another image view. That works fine but when I try to save it the image is always squished(may be a scale issue but it seems only the vertical size getting distorted.
This is the result of combining the images before trying to save it
This is after saving the image to the photos album
The image will not stay in the translated location and it's distorted.
Here is the code when I save the image
let fullSize:CGSize = photoView.image!.size
let newSize:CGSize = fullSize
let scale:CGFloat = newSize.height/fullSize.height
let offset:CGFloat = (newSize.width - fullSize.width*scale)/2
let offsetRect:CGRect = CGRect.init(x: offset, y: 0, width: newSize.width - offset*2, height: newSize.height)
UIGraphicsBeginImageContext(newSize);
self.photoView.image!.draw(in: offsetRect)
self.copiedView.image!.draw(in: CGRect.init(x: 0, y: 0, width: photoView.image!.size.width, height:photoView.image!.size.height))
let combImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext();
//photoView.image = combImage
UIImageWriteToSavedPhotosAlbum(combImage, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)
Any help is appreciated

How to create a UIImageView in Swift Playgrounds for iPad?

I was wondering how to create a UIImageView and set it’s image property and show it on the live view. This is Swift Playgrounds for iPad so there is no storyboards. I can’t add in a UIImageView unless I code it. How do I create a UIImageView in Swift Playgrounds for iPad?
let image = UIImage(named: “photo.png”)
let imageView = UIImageView()
imageView.image = image
view.addSubview(imageView)
imageView.Frame = CGRect(x: 0, y: 0, width: int, height: int)
This creates a custom frame. To have the frame match the image use imageView.image = UIImage(named: image) This is based of of rmaddy’s comment below

I need help integrating a specific UIImage resizing extension into my current draw CGRect function

I found this extension online, it allows me to have images adhere to aspect fit/fill even when drawn inside dynamically growing/shrinking image views (currently when image is saved to camera roll after my draw function the image reverts to "scale fill" regardless of what the content mode of the image view is. I suspect the reasoning for this is because I have it drawing the image to size/bounds of the image view, but since the image view is dynamic, i don't see any way around this without using this extension):
// MARK: - Image Scaling.
extension UIImage {
/// Scales an image to fit within a bounds with a size governed by the passed size. Also keeps the aspect ratio.
/// Switch MIN to MAX for aspect fill instead of fit.
///
/// - parameter newSize: newSize the size of the bounds the image must fit within.
///
/// - returns: a new scaled image.
func scaleImageToSize(newSize: CGSize) -> UIImage {
var scaledImageRect = CGRect.zero
let aspectWidth = newSize.width/size.width
let aspectheight = newSize.height/size.height
let aspectRatio = max(aspectWidth, aspectheight)
scaledImageRect.size.width = size.width * aspectRatio;
scaledImageRect.size.height = size.height * aspectRatio;
scaledImageRect.origin.x = (newSize.width - scaledImageRect.size.width) / 2.0;
scaledImageRect.origin.y = (newSize.height - scaledImageRect.size.height) / 2.0;
UIGraphicsBeginImageContext(newSize)
draw(in: scaledImageRect)
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return scaledImage!
}
}
This is my current function I'm using for drawing the image on screen to be able to save it to camera roll (this function combines two images, a frame and an image from camera roll:
func drawImagesAndText() {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: imageView.bounds.size.width, height: imageView.bounds.size.height))
img = renderer.image { ctx in
// var newSize = currentImage.scaleImageToSize
let bgImage = currentImage
bgImage?.draw(in: CGRect(x: 0, y: 0, width: imageView.bounds.size.width, height: imageView.bounds.size.height))
frames = UIImage(named: framesAr)
frames?.draw(in: CGRect(x: 0, y: 0, width: imageView.bounds.size.width, height: imageView.bounds.size.height))
}
}
All the tutorials I've found on how to use extensions don't cover how to pass in and out variables like this one requires. Any insight would be greatly appreciated.
I understand that you don't know how to use the extension, is that correct? Since it just adds a function to every UIImage, you can simply call it on your image like this: currentImage.scaleImageToSize(newSize: someSize) and pass the size you want the image to fit into.
Dorian Roy was telling me to use that call in place of using just "currentImage", and that's what worked!
(I commented on his initial answer saying I was having issues because I was trying to use the return value from the extension itself in place of "currentImage")

controll the size of image assigned to the background by ui colorpattern

I assign an image to the background so the user can draw on it but the image always is not in the right size it takes like 1/3 of it and assigns it to the image view
the only way to bypass this is to make a canvas exactly the size of the image assigned like in PICSART app,
does any one knows how to do this?
mainimageview.backgroundColor = UIColor(patternImage: "draw")
`
You can write your own method to resize the image you want at the time of assigning background color. Pass your image and size you want
func imageWithImage(image:UIImage?, newSize:CGFloat)->UIImage?
{
let size = CGSizeMake(newSize, newSize)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
image?.drawInRect(CGRectMake(0, 0, size.width, size.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}

How to scale up an UIImage without smoothening anything?

I want to scale up an UIImage in such a way, that the user can see the pixels in the UIImage very sharp. When I put that to an UIImageView and scale the transform matrix up, the UIImage appears antialiased and smoothed.
Is there a way to render in a bigger bitmap context by simply repeating every row and every column to get bigger pixels? How could I do that?
#import <QuartzCore/CALayer.h>
view.layer.magnificationFilter = kCAFilterNearest
When drawing directly into bitmap context, we can use:
CGContextSetInterpolationQuality(myBitmapContext, kCGInterpolationNone);
I found this on CGContextDrawImage very slow on iPhone 4
Swift 5
let image = UIImage(named: "Foo")
let scaledImageSize = image.size.applying(CGAffineTransform(scaleX: 2, y: 2))
UIGraphicsBeginImageContext(scaledImageSize)
let scaledContext = UIGraphicsGetCurrentContext()!
scaledContext.interpolationQuality = .none
image.draw(in: CGRect(origin: .zero, size: scaledImageSize))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()!
I was also trying this (on a sublayer) and I couldn't get it working, it was still blurry. This is what I had to do:
const CGFloat PIXEL_SCALE = 2;
layer.magnificationFilter = kCAFilterNearest; //Nearest neighbor texture filtering
layer.transform = CATransform3DMakeScale(PIXEL_SCALE, PIXEL_SCALE, 1); //Scale layer up
//Rasterize w/ sufficient resolution to show sharp pixels
layer.shouldRasterize = YES;
layer.rasterizationScale = PIXEL_SCALE;
For UIImage created from CIImage you may use:
imageView.image = UIImage(CIImage: ciImage.imageByApplyingTransform(CGAffineTransformMakeScale(kScale, kScale)))