Blend Uicolors in Swift

Blend UIColors in Swift

How about something like this:

func addColor(_ color1: UIColor, with color2: UIColor) -> UIColor {
var (r1, g1, b1, a1) = (CGFloat(0), CGFloat(0), CGFloat(0), CGFloat(0))
var (r2, g2, b2, a2) = (CGFloat(0), CGFloat(0), CGFloat(0), CGFloat(0))

color1.getRed(&r1, green: &g1, blue: &b1, alpha: &a1)
color2.getRed(&r2, green: &g2, blue: &b2, alpha: &a2)

// add the components, but don't let them go above 1.0
return UIColor(red: min(r1 + r2, 1), green: min(g1 + g2, 1), blue: min(b1 + b2, 1), alpha: (a1 + a2) / 2)
}

func multiplyColor(_ color: UIColor, by multiplier: CGFloat) -> UIColor {
var (r, g, b, a) = (CGFloat(0), CGFloat(0), CGFloat(0), CGFloat(0))
color.getRed(&r, green: &g, blue: &b, alpha: &a)
return UIColor(red: r * multiplier, green: g * multiplier, blue: b * multiplier, alpha: a)
}

Define operators to add colors and multiply a color by a Double:

func +(color1: UIColor, color2: UIColor) -> UIColor {
return addColor(color1, with: color2)
}

func *(color: UIColor, multiplier: Double) -> UIColor {
return multiplyColor(color, by: CGFloat(multiplier))
}

Then you can blend colors like this:

// Make orange with 50% red and 50% yellow    
let orange = .red * 0.5 + .yellow * 0.5

// Make light gray with 25% black and 75% white
let lightGray = .black * 0.25 + .white * 0.75

// Make sky blue by lightening a combination of 25% blue and 75% cyan
let skyBlue = (.blue * 0.25 + .cyan * 0.75) * 0.25 + .white * 0.75

// Make dark red by combining 50% red and 50% black
let darkRed = .red * 0.50 + .black * 0.50

// Make purple from 60% blue and 40% red
let purple = (.blue * 0.60 + .red * 0.40)

// Then make lavender from 25% purple and 75% white
let lavender = purple * 0.25 + .white * 0.75

Can I mix two UIColor together?

You can't mix two UIColors directly as you mention in your question. Anyways there is an example to mix two colors using other schemes. The link for same is as follows:

Link Here

How to get mid color between two UIColors in iOS

A straightforward way of finding the "in between" is to average the four components, like this:

UIColor *color1 = [UIColor blackColor];
UIColor *color2 = [UIColor whiteColor];
CGFloat r1, r2, g1, g2, b1, b2, a1, a2;
[color1 getRed:&r1 green:&g1 blue:&b1 alpha:&a1];
[color2 getRed:&r2 green:&g2 blue:&b2 alpha:&a2];
UIColor *avg = [UIColor colorWithRed:(r1+r2)/2.0f
green:(g1+g2)/2.0f
blue:(b1+b2)/2.0f
alpha:(a1+a2)/2.0f];

Note that this produces a midpoint RGBA color space, which is only one of many possible color spaces. Averaging components in other color spaces will lead to a different result.

iOS (Swift): representing scaled value as UIColor

Here's a helpful UIColor extension that lets you get a blend between two colors based on a percentage.

extension UIColor {
// This function calculates a new color by blending the two colors.
// A percent of 0.0 gives the "self" color
// A percent of 1.0 gives the "to" color
// Any other percent gives an appropriate color in between the two
func blend(to: UIColor, percent: Double) -> UIColor {
var fR : CGFloat = 0.0
var fG : CGFloat = 0.0
var fB : CGFloat = 0.0
var tR : CGFloat = 0.0
var tG : CGFloat = 0.0
var tB : CGFloat = 0.0

getRed(&fR, green: &fG, blue: &fB, alpha: nil)
to.getRed(&tR, green: &tG, blue: &tB, alpha: nil)

let dR = tR - fR
let dG = tG - fG
let dB = tB - fB

let perc = min(1.0, max(0.0, percent))
let rR = fR + dR * CGFloat(perc)
let rG = fG + dG * CGFloat(perc)
let rB = fB + dB * CGFloat(perc)

return UIColor(red: rR, green: rG, blue: rB, alpha: 1.0)
}
}

Examples:

let red = UIColor.red.blend(to: .green, percent: 0)
let mix = UIColor.red.blend(to: .green, percent: 0.5)
let green = UIColor.red.blend(to: .green, percent: 1)

Blend 2 views with a custom color in swift?

You can’t do that with a mere blend mode. You would need to use a CIFilter. Or just use two labels, one green, one white, and mask them both, with inverse masks.

How to mix two colors in SwitUI?

Since you are working in iOS, you can take advantage of the fact that a SwiftUI Color can be created from a UIColor.

Using UIColor.blend from this answer you can create a blend of 2 UIColors by specifying the colors and the intensity (0.0 ... 1.0) for each. For example, to create a foreground color for Text that is 80% UIColor.green and 20% UIColor.black:

struct ContentView: View {
var body: some View {
Text("Hello World!")
.foregroundColor(Color(UIColor.blend(color1: .green, intensity1: 0.8, color2: .black, intensity2: 0.2)))
}
}

Note: Just include the UIColor extension in any file in your project. It is a good practice to give extensions their own file(s), but you can include it in the same file as your View if you want.

UIImageView Is Blending Colors With No Alpha

The problem is that this:

setColorFor(255, g: 0, b: 0, a: 0, x: x, y: y)

is not a valid .premultipliedLast color value. Premultiplied means that the colors have already been multiplied by the alpha. If you multiply 255 by 0 you get 0, so that is the correct red value here — as the result in rows 10-12 demonstrates.

You would probably confuse yourself a lot less if you would just construct the image using UIGraphicsImageRenderer in the normal way rather than a raw bitmap context. But of course if your use case precludes that, then by all means use the bitmap — but then there is a lot more room for you to use it incorrectly.

Swift - How to use UIGraphics blend mode?

Based on @matt's answer using .sourceAtop I found a working solution for WatchKit:

let size = CGSize(width: 300, height: 100)
UIGraphicsBeginImageContext(size)

let context = UIGraphicsGetCurrentContext()!
let count = 5;
let padding = (size.width / CGFloat(count)) * 0.5
for i in 0...count {
let offsetX = size.width * (CGFloat(i) / CGFloat(count))
let rect = CGRect(x: offsetX + padding/2, y: 0, width: padding, height: size.height)
context.setFillColor(UIColor.green.cgColor)
context.fill(rect)
}

context.setFillColor(UIColor.red.cgColor)
context.setBlendMode(CGBlendMode.sourceAtop)
context.fill(CGRect(x: 0.0, y: 0.0, width: size.width * 0.5, height: size.height))

UIGraphicsEndImageContext()

CGColor - Determining the blended color from two UIViews that are on top of each other

Heres a tutorial-ish thing:

Blending Modes in iOS

And here is the Apple Documentation that covers blend modes. Should get you on the right track. The exact formulas are shown for each blend mode option.

Finally, see this answer:

How to get the color of a displayed pixel

blendedColorWithFraction:ofColor:' in iOS Swift and ObjC

Here is the method implementation if you don't want to use StyleKit:

extension UIColor {
func blendedColorWithFraction(fraction: CGFloat, ofColor color: UIColor) -> UIColor {
var r1: CGFloat = 1.0, g1: CGFloat = 1.0, b1: CGFloat = 1.0, a1: CGFloat = 1.0
var r2: CGFloat = 1.0, g2: CGFloat = 1.0, b2: CGFloat = 1.0, a2: CGFloat = 1.0

self.getRed(&r1, green: &g1, blue: &b1, alpha: &a1)
color.getRed(&r2, green: &g2, blue: &b2, alpha: &a2)

return UIColor(red: r1 * (1 - fraction) + r2 * fraction,
green: g1 * (1 - fraction) + g2 * fraction,
blue: b1 * (1 - fraction) + b2 * fraction,
alpha: a1 * (1 - fraction) + a2 * fraction);
}
}


Related Topics



Leave a reply



Submit