IOS mix mode multiplies

I am looking for a solution to create this red window:

enter image description here

It uses the "Multiply" color filter. Currently I found this information: https://developer.apple.com/library/mac/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_images/dq_images.html

But how can I use something like the multiplication effect on a UIView, or is this not possible? Thus, the background is a UIImageView, and the red box is a UIView with the multiply effect.

+6
source share
2 answers

This quick expansion did the trick for me.

extension UIImage { //creates a static image with a color of the requested size static func fromColor(color: UIColor, size: CGSize) -> UIImage { let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) UIGraphicsBeginImageContext(rect.size) let context = UIGraphicsGetCurrentContext() CGContextSetFillColorWithColor(context, color.CGColor) CGContextFillRect(context, rect) let img = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return img } func blendWithColorAndRect(blendMode: CGBlendMode, color: UIColor, rect: CGRect) -> UIImage { let imageColor = UIImage.fromColor(color, size:self.size) let rectImage = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height) UIGraphicsBeginImageContextWithOptions(self.size, true, 0) let context = UIGraphicsGetCurrentContext() // fill the background with white so that translucent colors get lighter CGContextSetFillColorWithColor(context, UIColor.whiteColor().CGColor) CGContextFillRect(context, rectImage) self.drawInRect(rectImage, blendMode: .Normal, alpha: 1) imageColor.drawInRect(rect, blendMode: blendMode, alpha: 1) // grab the finished image and return it let result = UIGraphicsGetImageFromCurrentImageContext() //self.backgroundImageView.image = result UIGraphicsEndImageContext() return result } } 

Swift 3:

 static func fromColor(color: UIColor, size: CGSize) -> UIImage { let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) UIGraphicsBeginImageContext(rect.size) let context = UIGraphicsGetCurrentContext() context!.setFillColor(color.cgColor) context!.fill(rect) let img = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return img! } func blendWithColorAndRect(blendMode: CGBlendMode, color: UIColor, rect: CGRect) -> UIImage { let imageColor = UIImage.fromColor(color: color, size:self.size) let rectImage = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height) UIGraphicsBeginImageContextWithOptions(self.size, true, 0) let context = UIGraphicsGetCurrentContext() // fill the background with white so that translucent colors get lighter context!.setFillColor(UIColor.white.cgColor) context!.fill(rectImage) self.draw(in: rectImage, blendMode: .normal, alpha: 1) imageColor.draw(in: rect, blendMode: blendMode, alpha: 1) // grab the finished image and return it let result = UIGraphicsGetImageFromCurrentImageContext() //self.backgroundImageView.image = result UIGraphicsEndImageContext() return result! } 

But it works only for images, I also want to work with video: |

+2
source

I expanded @pegpeg solution and added gradient overlay on image instead of single color

Swift 4:

 static func fromGradient(colors: [UIColor], locations: [CGFloat], horizontal: Bool, size: CGSize) -> UIImage { let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) UIGraphicsBeginImageContext(rect.size) let context = UIGraphicsGetCurrentContext() let colorSpace = CGColorSpaceCreateDeviceRGB() let cgColors = colors.map {$0.cgColor} as CFArray let grad = CGGradient(colorsSpace: colorSpace, colors: cgColors , locations: locations) let startPoint = CGPoint(x: 0, y: 0) let endPoint = horizontal ? CGPoint(x: size.width, y: 0) : CGPoint(x: 0, y: size.height) context?.drawLinearGradient(grad!, start: startPoint, end: endPoint, options: .drawsAfterEndLocation) let img = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return img! } func blendWithGradientAndRect(blendMode: CGBlendMode, colors: [UIColor], locations: [CGFloat], horizontal: Bool = false, alpha: CGFloat = 1.0, rect: CGRect) -> UIImage { let imageColor = UIImage.fromGradient(colors: colors, locations: locations, horizontal: horizontal, size: size) let rectImage = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height) UIGraphicsBeginImageContextWithOptions(self.size, true, 0) let context = UIGraphicsGetCurrentContext() // fill the background with white so that translucent colors get lighter context!.setFillColor(UIColor.white.cgColor) context!.fill(rectImage) self.draw(in: rectImage, blendMode: .normal, alpha: 1) imageColor.draw(in: rect, blendMode: blendMode, alpha: alpha) // grab the finished image and return it let result = UIGraphicsGetImageFromCurrentImageContext() //self.backgroundImageView.image = result UIGraphicsEndImageContext() return result! } 

an array of colors should have the same length of an array of locations, for example:

 let newImage = image.blendWithGradientAndRect(blendMode: .multiply, colors: [.red, .white], locations: [0,1], horizontal: true, alpha: 0.8, rect: imageRect) 
0
source

All Articles