How to add corner smoothing to UIImageView? - uiimage

I have an image with which I perform editing actions
now I'm trying to make the logic of smoothing the edges just for the picture, not for the imageView
the user must pass a value with which the edges of the image should be smoothed
I tried to use this code but it doesn't work for me
func image(withRoundedCornersRadius radius: CGFloat) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, 0)
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
UIBezierPath(roundedRect: rect, cornerRadius: CGFloat(radius)).addClip()
draw(in: rect)
let roundedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return roundedImage
}

Related

Kotlin: How can I crop Image with 4 points (coordinates)

I want to crop image with 4 points
Four points mean (x1, y1), (x2, y2), (x3, y3), (x4, y4).
In Swift(iOS), I can do that with below code.
func pointToRect(pointsArray: [CGPoint]) -> CGRect {
var greatestXValue = pointsArray[0].x
var greatestYValue = pointsArray[0].y
var smallestXValue = pointsArray[0].x
var smallestYValue = pointsArray[0].y
for point in pointsArray {
greatestXValue = max(greatestXValue, point.x);
greatestYValue = max(greatestYValue, point.y);
smallestXValue = min(smallestXValue, point.x);
smallestYValue = min(smallestYValue, point.y);
}
let origin = CGPoint(x: smallestXValue, y: smallestYValue)
let size = CGSize(width: greatestXValue - smallestXValue, height: greatestYValue - smallestYValue)
return CGRect(origin: origin, size: size)
}
let eyesRect = pointToRect(pointsArray: [points[33], points[5], points[46], points[28]])
func cropped(rect: CGRect) -> UIImage? {
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
let drawRect = CGRect(x: -rect.origin.x, y: -rect.origin.y,
width: self.size.width, height: self.size.height)
context?.clip(to: CGRect(x: 0, y: 0,
width: rect.size.width, height: rect.size.height))
self.draw(in: drawRect)
let subImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return subImage
}
croppedFaceImage = image.cropped(rect: eyesRect)
I have originalImage, 4 points coordinates.
How can I crop them and get cropped image.
Thank you for reading it.

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

How to update a SceneKit scene with SwiftUI?

I have a cylinder as SCNCylinder in a SCNScene in SceneKit and want to display it in a frame in SwiftUI. My goal is to rotate the cylinder by a angle of 180° or 90° (as the user chooses). To take the input (of the angle of rotation) i have used Text() and onTapGesture{ .... } property in SwiftUI. After I tap the text, the cylinder rotates but now I have two cylinders, one at the original position and one rotating at an desired angle. I am not sure why this happens. I want the same cylinder to rotate, not a identical copy of that doing it. I have connected the SwiftUI view and SceneKit view by using #State and #Binding.
Here is my code :
struct ContentView: View {
#State var rotationAngle = 0
var body: some View {
VStack{
Text("180°").onTapGesture {
self.rotationAngle = 180
}
Spacer()
Text("90°").onTapGesture {
self.rotationAngle = 90
}
SceneKitView(angle: $rotationAngle)
.position(x: 225.0, y: 200)
.frame(width: 300, height: 300, alignment: .center)
}
}
}
struct SceneKitView: UIViewRepresentable {
#Binding var angle: Int
func degreesToRadians(_ degrees: Float) -> CGFloat {
return CGFloat(degrees * .pi / 180)
}
func makeUIView(context: UIViewRepresentableContext<SceneKitView>) -> SCNView {
let sceneView = SCNView()
sceneView.scene = SCNScene()
sceneView.allowsCameraControl = true
sceneView.autoenablesDefaultLighting = true
sceneView.backgroundColor = UIColor.white
sceneView.frame = CGRect(x: 0, y: 10, width: 0, height: 1)
return sceneView
}
func updateUIView(_ sceneView: SCNView, context: UIViewRepresentableContext<SceneKitView>) {
let cylinder = SCNCylinder(radius: 0.02, height: 2.0)
let cylindernode = SCNNode(geometry: cylinder)
cylindernode.position = SCNVector3(x: 0, y: 0, z: 0)
cylinder.firstMaterial?.diffuse.contents = UIColor.green
cylindernode.pivot = SCNMatrix4MakeTranslation(0, -1, 0)
let inttofloat = Float(self.angle)
let rotation = SCNAction.rotate(by: self.degreesToRadians(inttofloat), around: SCNVector3(1, 0, 0), duration: 5)
cylindernode.runAction(rotation)
sceneView.scene?.rootNode.addChildNode(cylindernode)
}
typealias UIViewType = SCNView
}
I want to have a single cylinder rotation at a given angle.
The problem is, that updateUIView will be called several times. You can check this by adding a debug point there. Because of that your cylinder will be added several times. So you can solve this by many ways...one way would be to delete all nodes in your sceneview before starting your animation like so:
func updateUIView(_ sceneView: SCNView, context: UIViewRepresentableContext<SceneKitView>) {
sceneView.scene?.rootNode.enumerateChildNodes { (node, stop) in
node.removeFromParentNode()
}

CGRectMake, CGPointMake, CGSizeMake, CGRectZero, CGPointZero is unavailable in Swift

After converting code to latest swift 3.0 I am shown this error.
Also tell me solution for CGSize = CGSizeMake(0,0)
static var frameAtStartOfPan: CGRect = CGRectZero
static var startPointOfPan: CGPoint = CGPointZero
Which is also unavailable.
CGRect Can be simply created using an instance of a CGPoint or CGSize, thats given below.
let rect = CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: 100, height: 100))
// Or
let rect = CGRect(origin: .zero, size: CGSize(width: 100, height: 100))
Or if we want to specify each value in CGFloat or Double or Int, we can use this method.
let rect = CGRect(x: 0, y: 0, width: 100, height: 100) // CGFloat, Double, Int
CGPoint Can be created like this.
let point = CGPoint(x: 0,y :0) // CGFloat, Double, Int
CGSize Can be created like this.
let size = CGSize(width: 100, height: 100) // CGFloat, Double, Int
Also size and point with 0 as the values, it can be done like this.
let size = CGSize.zero // width = 0, height = 0
let point = CGPoint.zero // x = 0, y = 0, equal to CGPointZero
let rect = CGRect.zero // equal to CGRectZero
CGRectZero & CGPointZero replaced with CGRect.zero & CGPoint.zero in Swift 3.0.
Quick fix for CGRectMake , CGPointMake, CGSizeMake in Swift3 & iOS10
Add these extensions :
extension CGRect{
init(_ x:CGFloat,_ y:CGFloat,_ width:CGFloat,_ height:CGFloat) {
self.init(x:x,y:y,width:width,height:height)
}
}
extension CGSize{
init(_ width:CGFloat,_ height:CGFloat) {
self.init(width:width,height:height)
}
}
extension CGPoint{
init(_ x:CGFloat,_ y:CGFloat) {
self.init(x:x,y:y)
}
}
Then go to "Find and Replace in Workspace"
Find CGRectMake , CGPointMake, CGSizeMake and Replace them with CGRect , CGPoint, CGSize
These steps might save all the time as Xcode right now doesn't give us quick conversion from Swift 2+ to Swift 3
In Swift 3, you can simply use CGPoint.zero or CGRect.zero in place of CGRectZero or CGPointZero.
However, in Swift 4, CGRect.zero and 'CGPoint.zero' will work
If you want to use them as in swift 2, you can use these funcs:
For CGRectMake:
func CGRectMake(_ x: CGFloat, _ y: CGFloat, _ width: CGFloat, _ height: CGFloat) -> CGRect {
return CGRect(x: x, y: y, width: width, height: height)
}
For CGPointMake:
func CGPointMake(_ x: CGFloat, _ y: CGFloat) -> CGPoint {
return CGPoint(x: x, y: y)
}
For CGSizeMake:
func CGSizeMake(_ width: CGFloat, _ height: CGFloat) -> CGSize {
return CGSize(width: width, height: height)
}
Just put them outside any class and it should work. (Works for me at least)
The structures as well as all other symbols in Core Graphics and other APIs have become cleaner and also include parameter names.
https://developer.apple.com/reference/coregraphics#symbols
CGRect(x: Int, y: Int, width: Int, height: Int)
CGVector(dx: Int, dy: Int)
CGPoint(x: Double, y: Double)
CGSize(width: Int, height: Int)
CGPoint Example:
let newPoint = stackMid.convert(CGPoint(x: -10, y: 10), to: self)
CGVector Example:
self.physicsWorld.gravity = CGVector(dx: 0, dy: gravity)
CGSize Example:
hero.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 16, height: 18))
CGRect Example:
let back = SKShapeNode(rect: CGRect(x: 0-120, y: 1024-200-30, width: 240, height: 140), cornerRadius: 20)
Apple Blog
Swift syntax and API renaming changes in Swift 3 make the language feel more natural, and provide an even more Swift-y experience when calling Cocoa frameworks. Popular frameworks Core Graphics and Grand Central Dispatch have new, much cleaner interfaces in Swift.
Swift 3 Bonus: Why didn't anyone mention the short form?
CGRect(origin: .zero, size: size)
.zero instead of CGPoint.zero
When the type is defined, you can safely omit it.
Try the following:
var myToolBar = UIToolbar.init(frame: CGRect.init(x: 0, y: 0, width: 320, height: 44))
This is for the swift's latest version
You can use this with replacement of CGRectZero
CGRect.zero
For CGSize
CGSize(width: self.view.frame.width * 3, height: self.view.frame.size.height)
Instead of CGSizeMake add CGSize it will work.
CGSizeMake is used in objective c.
you don't want to use make with swift
In Swift 4 it works like below
collectionView.setContentOffset(CGPoint.zero, animated: true)

Why is UIBarButtonItem image always fuzzy/blurry/pixelated

Here is my current code:
var reply = UIBarButtonItem(image: UIImage(named: "reply"), style: UIBarButtonItemStyle.Plain, target: self, action: Selector("reply:"))
self.navigationItem.rightBarButtonItem = reply
The button in the top right corner is always fuzzy. This is a screenshot from an iPhone4s device so it is not a retina-related issue.
I have tried different image sizes ranging from 30x30 to 512x512 and adding the image using customView. These methods have not fixed the issue.
Thanks in advance.
I have solved it using this method:
var replyBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
replyBtn.setImage(UIImage(named: "reply"), forState: UIControlState.Normal)
replyBtn.addTarget(self.navigationController, action: Selector("reply:"), forControlEvents: UIControlEvents.TouchUpInside)
var item = UIBarButtonItem(customView: replyBtn)
self.navigationItem.rightBarButtonItem = item
It displays a very crisp button using the exact same image.
From IOS human interface guide the icon should be 22x22
Take a look at the documentation here:
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/BarIcons.html
Try this:
func createBarButton(image: String, size: CGSize, offset: (x: CGFloat, y: CGFloat) = (0,0), hightlightable: Bool = true, action: Selector) -> UIBarButtonItem {
let btn = UIButton(type: .custom)
let img = UIImage(named: image)
btn.setBackgroundImage(img, for: .normal)
btn.addTarget(self, action: action, for: .touchUpInside)
btn.frame = CGRect(x: offset.x, y: offset.y, width: size.width, height: size.height)
btn.adjustsImageWhenHighlighted = hightlightable
let view = UIView(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
// view.bounds = view.bounds.offsetBy(dx: offset.x, dy: offset.y)
view.addSubview(btn)
let barButton = UIBarButtonItem(customView: view)
return barButton
}
self.navigationItem.rightBarButtonItem = createBarButton(image: "YOUR_IMAGE",
size: CGSize(width: 35, height: 35),
offset: (x: -10, y: 0),
action: #selector(showXY))

Resources