Fill UIImage with UIColor
You need to end the image context when you finish drawing:
UIGraphicsEndImageContext();
Or you could add a category method for UIImage:
- (UIImage *)imageByTintColor:(UIColor *)color
{
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
[color set];
UIRectFill(rect);
[self drawAtPoint:CGPointMake(0, 0) blendMode:kCGBlendModeDestinationIn alpha:1];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Using as:
image = [image imageByTintColor:color];
Create UIImage with solid color in Swift
Another nice solution,
Swift 3.0
public extension UIImage {
convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
color.setFill()
UIRectFill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
guard let cgImage = image?.cgImage else { return nil }
self.init(cgImage: cgImage)
}
}
Swift 2.2 compatible, is to create another constructor in UIImage, in this way:
public extension UIImage {
public convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
color.setFill()
UIRectFill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
guard let cgImage = image?.CGImage else { return nil }
self.init(CGImage: cgImage)
}
}
In this way you can create the custom colored-image in this way:
let redImage = UIImage(color: .redColor())
Or, optionally, create the image with a custom size:
let redImage200x200 = UIImage(color: .redColor(), size: CGSize(width: 200, height: 200))
How to change the color of a UIImage in Swift
edit/update:
For iOS10+ we can use UIGraphicsImageRenderer:
Xcode 11 • Swift 5.1
extension UIImage {
func tinted(with color: UIColor, isOpaque: Bool = false) -> UIImage? {
let format = imageRendererFormat
format.opaque = isOpaque
return UIGraphicsImageRenderer(size: size, format: format).image { _ in
color.set()
withRenderingMode(.alwaysTemplate).draw(at: .zero)
}
}
}
Playground Testing
let camera = UIImage(data: try! Data(contentsOf: URL(string: "https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-camera-128.png")!))!
let redCamera = camera.tinted(with: .red)
original answer
You can use UIGraphicsBeginImageContextWithOptions to begin an image context, set the desired color and use image's method func draw(in rect: CGRect)
to draw your icon image using rendering mode .alwaysTemplate
on it:
extension UIImage {
func tinted(with color: UIColor) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
defer { UIGraphicsEndImageContext() }
color.set()
withRenderingMode(.alwaysTemplate)
.draw(in: CGRect(origin: .zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
}
How to fill with color the transparent part of the UIImage?
For this it would be better to just use the cloud texture as is an then color blend your SKSpriteNode.
https://developer.apple.com/reference/spritekit/skspritenode/1519639-color
Note you'll need to set the colorBlendFactor as well. The default is 0.
https://developer.apple.com/reference/spritekit/skspritenode/1519780-colorblendfactor
Colorize a UIImage in Swift
I finally wrote a CIColorKernel, as @dfd suggested and it works fine:
class ColorFilter: CIFilter {
var inputImage: CIImage?
var inputColor: CIColor?
let kernel: CIColorKernel = {
let kernelString = "kernel vec4 colorize(__sample pixel, vec4 color)\n"
+ "{\n"
+ " pixel.rgb = color.rgb;\n"
+ " return pixel;\n"
+ "}\n"
return CIColorKernel(source: kernelString)!
}()
override var outputImage: CIImage? {
guard let inputImage = inputImage else {
print("\(self) cannot produce output because no input image provided.")
return nil
}
guard let inputColor = inputColor else {
print("\(self) cannot produce output because no input color provided.")
return nil
}
let inputs = [inputImage, inputColor] as [Any]
return kernel.apply(extent: inputImage.extent, arguments: inputs)
}
}
To summarize, the CIColorMatrix I used first seems not to be linear (when using the bias vector). Giving a red 0,5 (float) value did not output an image with red 127 color in the [0-255] interval.
Writing a custom filter was my solution.
How to create a colored 1x1 UIImage on the iPhone dynamically?
You can use CGContextSetFillColorWithColor
and CGContextFillRect
for this:
Swift
extension UIImage {
class func image(with color: UIColor) -> UIImage {
let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, color.CGColor)
CGContextFillRect(context, rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
Swift3
extension UIImage {
class func image(with color: UIColor) -> UIImage {
let rect = CGRect(origin: CGPoint(x: 0, y:0), size: CGSize(width: 1, height: 1))
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()!
context.setFillColor(color.cgColor)
context.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
Objective-C
+ (UIImage *)imageWithColor:(UIColor *)color {
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Related Topics
Disable Vertical Scroll in Uiscrollview Swift
Moya/Alamofire - Url Encoded Params with Same Keys
How to Use a Generic Class Without the Type Argument in Swift
Swift Get Specific Value from Firebase Database
Didbegincontact Passed Pkphyicsobject
Openurl in Appdelegate Conversion Error Nsstring -> String (Swift & iOS8)
How to Use a Uisplitviewcontroller in Swift
Masked Uivisualeffectview Does Not Work on iOS 10
How to Create a CSV File from Core Data (Swift)
How to Keep the Header Cell Moving with the Tableview Cells in Swift 2.0
Self Sizing Uitextview Till Specific Height
How to Monitor More Than 20 Regions
Unusernotificationcenter.Current().Getdeliverednotifications Only Ever Returns an Empty Array
Save Image with the Correct Orientation - Swift & Core Image
Swift 3 Nscache Generic Parameter 'Keytype' Could Not Be Inferred
How Do Ruler Apps Stay Accurate on All Devices