swift - can't change UIImage tintColor - swift

I have a pattern PNG image, with black dots on transparent background, and I need to change dot's color at custom colors, for example yellow
I'm trying to change tint color before drawing it, but image is still black on transparent
let templateImage = UIImage(named: "spray7")!.withTintColor(.yellow, renderingMode: .alwaysTemplate)
let image = templateImage.cgImage
context.draw(image!, in: CGRect(x: 0, y: 0, width: 8, height: 8))
and context is a CGContext
Any adviŅe will be helpful!

correct way is to use
let templateImage = UIImage(named: "spray7")!.tinted(with: .yellow)
instead

Related

How to overlay an image on top of another image

I am working on creating a small word guessing app for a school assignment in uikit and I have been trying to figure out a way to overlay an image that updates based on the amount of incorrect guesses left on top of another image. I've spent almost 2 1/2 hours checking and I could not find a single method that worked.
So far this is what I've tried
let bgimg = UIImage(named: "background") // The image used as a background
let bgimgview = UIImageView(image: bgimg) // Create the view holding the image
bgimgview.frame = CGRect(x: 0, y: 0, width: 500, height: 500) // The size of the background image
let frontimg = UIImage(named: "Tree \(currentGame.incorrectMovesRemaining)") // The image in the foreground
let frontimgview = UIImageView(image: frontimg) // Create the view holding the image
frontimgview.frame = CGRect(x: 150, y: 300, width: 50, height: 50) // The size and position of the front image
bgimgview.addSubview(frontimgview) // Add the front image on top of the background
I commented this one out so that my code could work
let bottomImage = UIImage(named: "background")!
// let topImage = UIImage(named: "Tree \(currentGame.incorrectMovesRemaining)")!
// let rect = CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: 100, height: 100))
// let newSize = rect.size // set this to what you need
// UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
//
// bottomImage.draw(in: rect)
// topImage.draw(in: rect)
//
// let newImage = UIGraphicsGetImageFromCurrentImageContext()
// UIGraphicsEndImageContext()
// }
//
// var backgroundImageButton: UIButton! {
// backgroundImageButton.setBackgroundImage(newImage)
You should be able to do this by adjusting the alpha value of the foreground image view. Alpha controls the transparency of a view-- an alpha of 1.0 makes it opaque, a value of 0 is invisible, and values between 0 and 1 make a view more or less transparent. If you have the two image views aligned so that one covers the other, you can set the foreground image alpha to any value from 0 to 1 to adjust how transparent it is.

How to merge 2 pdf vector image assets in Swift

I have two vector images. I want to merge them so the dots appear on top of the first image.
The solutions for regular png assets don't work, as they use the actual size of the image, and the combined image comes out very blurry.
One solution that I found was placing a second UIImageView (same size, centred) on top of the first one, but it seems really dumb.
I need to make this inside the app because I also want to have the squared coloured differently (change the tint of the vector), and then merged with the black border image. So I can have 3 assets in my project (square, border and dots).
Figured out a way to do this in an extension to UIImageView. Surprised that I couldn't find this anywhere.
extension UIImageView {
func mergeTwoPDF(one: UIImage, two: UIImage) {
UIGraphicsBeginImageContextWithOptions(self.frame.size, false, UIScreen.main.scale)
let areaSize = CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height)
one.draw(in: areaSize, blendMode: .normal, alpha: 1.0)
two.draw(in: areaSize, blendMode: .normal, alpha: 1.0)
//If you want to merge more than 2 images, just add them to the func parameters and repeat the line above with them
let mergedImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
self.image = mergedImage
}
}
I suggest using sublayers:
["firstOne", "secondOne"].forEach {
let myLayer = CALayer()
let myImage = UIImage(named: $0)?.cgImage
myLayer.frame = myView.bounds
myLayer.contents = myImage
myView.layer.addSublayer(myLayer)
}
Or create a custom layer class

Change UIImage color without using Uiimageview in swift3

I want draw image pattern like star, one can change the color for that. Can I change the color of Image itself without using image view? I saw many answer changing tint color of UIImageview, but the effect is not applied to UIImage
Thank you all for the answers, but I got the solution working.
func changePatternImageColor() {
patternImage = UIImage(named: "pattern_star.png")! //make sure to reinitialize the original image here every time you change the color
UIGraphicsBeginImageContext(patternImage.size)
let context = UIGraphicsGetCurrentContext()
let color = UIColor(red: self.red, green: self.green, blue: self.blue, alpha: self.opacity)
color.setFill()
context?.translateBy(x: 0, y: patternImage.size.height)
context?.scaleBy(x: 1.0, y: -1.0)
//set the blend mode to color burn, and the original image
context?.setBlendMode(CGBlendMode.exclusion) //this does the magic.
let rect = CGRect(x: 0, y: 0, width: patternImage.size.height, height: patternImage.size.height)
context?.draw(patternImage.cgImage!, in: rect)
//set the mask that matches the shape of the image, then draw color burn a colored rectangle
context?.clip(to: rect, mask: patternImage.cgImage!)
context?.addRect(rect)
context?.drawPath(using: CGPathDrawingMode.fill)
patternImage = UIGraphicsGetImageFromCurrentImageContext()!
image_ref = patternImage.cgImage
UIGraphicsEndImageContext()
}
The patternImage is the the image added in asset.
P.S. the patternImage added in asset SHOULD be in black color
tintColor is not only a property of a UIImageView, it is a property of a UIView, as long as your image is in a UIView, you can use UIView.tintColor.

Swift: draw image and border using UIGraphicsBeginImageContextWithOptions

I need to draw an image like this
What provided is: green bubble with down arrow image(green bubble image already have border so I don't need to draw it) and center photo. And I need to draw white border around the photo + rounded corner it
This is the code I have so far:
let rect = CGRect(origin: .zero, size: CGSize(width: 60, height: 67))
let width = CGFloat(50)
let borderWidth: CGFloat = 1.0
let imageRect = CGRect(x: 5, y: 5, width: width, height: width)
let bubbleImg = #imageLiteral(resourceName: "pinGreen")
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
let context = UIGraphicsGetCurrentContext()
bubbleImg.draw(in: rect)
let path = UIBezierPath(roundedRect: imageRect.insetBy(dx: borderWidth / 2, dy: borderWidth / 2), cornerRadius: width/2)
context!.saveGState()
path.addClip()
image.draw(in: imageRect)
context!.restoreGState()
UIColor.purple.setStroke()
path.lineWidth = borderWidth
path.stroke()
let roundedImage = UIGraphicsGetImageFromCurrentImageContext();
let img = roundedImage?.cgImage!
UIGraphicsEndImageContext();
and this is the result
Can anyone help me with this?
Is there anyway to design and get this type of image from xib file?
I will tell you the simplest way:
You need imageView1 for green bubble image, imageView2 for the photo (width=height). Their centers are the same.
The imageView2 has corner radius equal to its frame width/2.
Set border color of imageView2's layer to White, and border width is about 5 px. Dont forget to set maskToBounds=true.
Please try.
DaijDjan: this answer in one image (showing IB + code + app):

how to change specific color in image to a different color

I have an UIView that its layer contents is an image.
let image = UIImage(names: "myImage")
layer.contents = image.CGImage
This image has a few colors.
Is there a way to change a specific color to any other color of my choice?
I found answers for changing the all of the colors in the image but not a specific one.
answer
You can't change specific color in PNG with transparent background, but.. i found the solution.
extension UIImage {
func maskWithColors(color: UIColor) -> UIImage? {
let maskingColors: [CGFloat] = [100, 255, 100, 255, 100, 255] // We should replace white color.
let maskImage = cgImage! //
let bounds = CGRect(x: 0, y: 0, width: size.width * 3, height: size.height * 3) // * 3, for best resolution.
let sz = CGSize(width: size.width * 3, height: size.height * 3) // Size.
var returnImage: UIImage? // Image, to return
/* Firstly we will remove transparent background, because
maskingColorComponents don't work with transparent images. */
UIGraphicsBeginImageContextWithOptions(sz, true, 0.0)
let context = UIGraphicsGetCurrentContext()!
context.saveGState()
context.scaleBy(x: 1.0, y: -1.0) // iOS flips images upside down, this fix it.
context.translateBy(x: 0, y: -sz.height) // and this :)
context.draw(maskImage, in: bounds)
context.restoreGState()
let noAlphaImage = UIGraphicsGetImageFromCurrentImageContext() // new image, without transparent elements.
UIGraphicsEndImageContext()
let noAlphaCGRef = noAlphaImage?.cgImage // get CGImage.
if let imgRefCopy = noAlphaCGRef?.copy(maskingColorComponents: maskingColors) { // Magic.
UIGraphicsBeginImageContextWithOptions(sz, false, 0.0)
let context = UIGraphicsGetCurrentContext()!
context.scaleBy(x: 1.0, y: -1.0)
context.translateBy(x: 0, y: -sz.height)
context.clip(to: bounds, mask: maskImage) // Remove background from image with mask.
context.setFillColor(color.cgColor) // set new color. We remove white color, and set red.
context.fill(bounds)
context.draw(imgRefCopy, in: bounds) // draw new image
let finalImage = UIGraphicsGetImageFromCurrentImageContext()
returnImage = finalImage! // YEAH!
UIGraphicsEndImageContext()
}
return returnImage
}
}
For call this function use code like this...
let image = UIImage(named: "Brush").maskWithColor(color: UIColor.red)
Result:
You can not change the image color... The only way is to change the image on any event or something...
Another variant is to create one image with transparent color, and set the background color of the view or something where you put the image...