Fill UIImage with UIColor - ios

I have a UIImage that I want to fill with UIColor
I've tried this code but the app crashes on the 10th row.
Here's the code:
extension UIImage {
func imageWithColor(_ color: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
let context = UIGraphicsGetCurrentContext()
context?.translateBy(x: 0.0, y: size.height)
context?.scaleBy(x: 1.0, y: -1.0)
context?.setBlendMode(CGBlendMode.normal)
let rect = CGRect(origin: CGPoint.zero, size: size)
context?.clip(to: rect, mask: context as! CGImage)// crashes
color.setFill()
context?.fill(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
return newImage!
}
}
The problem is probably on context?.clip(to: rect, mask: context as! CGImage) (I think I shouldn't send context as the mask, but what should I send? Both CGImage() and CGImage.self don't work.

You have to do as follow:
extension UIImage {
func tinted(with color: UIColor) -> UIImage? {
defer { UIGraphicsEndImageContext() }
UIGraphicsBeginImageContextWithOptions(size, false, scale)
color.set()
withRenderingMode(.alwaysTemplate).draw(in: CGRect(origin: .zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
}

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];

Simplest way to doing this
theImageView.image? = (theImageView.image?.imageWithRenderingMode(.AlwaysTemplate))!
theImageView.tintColor = UIColor.magentaColor()

let image = UIImage(named: "whatever.png")?.imageWithRenderingMode(.alwaysTemplate)
When you set this image later to UIButton or UIImageView - just change tint color of that control, and image will be drawn using tint color you specified.

Related

UIGraphicsBeginImageContextWithOptions adds odd opacity

I created an extension to UIImage and added the function imageWithColor(color: UIColor) that goes like this:
func imageWithColor(color: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
let context = UIGraphicsGetCurrentContext()
CGContextTranslateCTM(context, 0.0, size.height)
CGContextScaleCTM(context, 1.0, -1.0)
CGContextSetBlendMode(context, CGBlendMode.Normal)
let rect = CGRect(origin: CGPointZero, size: size)
CGContextClipToMask(context, rect, CGImage)
color.setFill()
CGContextFillRect(context, rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
return newImage
}
The problem is that when I display the image (using an UIImageView) it's being displayed with an odd opacity (like alpha 0.5 or something) and I can't understand why.
Any ideas why is it happening?

How can I change image tintColor

I'm receiving image from a server, then based on a color chosen by the user, the image color will be changed.
I tried the following :
_sketchImageView.image = [_sketchImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[_sketchImageView setTintColor:color];
i got the opposite of my goal (the white color outside UIImage is colored with the chosen color).
what is going wrong?
i need to do the same in this question,the provided solution doesn't solve my case.
How can I change image tintColor in iOS and WatchKit
Try to generate new image for yourself
UIImage *newImage = [_sketchImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIGraphicsBeginImageContextWithOptions(image.size, NO, newImage.scale);
[yourTintColor set];
[newImage drawInRect:CGRectMake(0, 0, image.size.width, newImage.size.height)];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
_sketchImageView.image = newImage;
And use it.
Good luck
======= UPDATE =======
This solution will only change color of all pixel's image.
Example: we have a book image: http://pngimg.com/upload/book_PNG2113.png
And after running above code (exp: TintColor is RED). We have:
SO: how your image is depends on how you designed it
In Swift you can use this extension: [Based on #VietHung's objective-c solution]
Swift 5:
extension UIImage {
func imageWithColor(color: UIColor) -> UIImage? {
var image = withRenderingMode(.alwaysTemplate)
UIGraphicsBeginImageContextWithOptions(size, false, scale)
color.set()
image.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
}
Previous Swift version:
extension UIImage {
func imageWithColor(color: UIColor) -> UIImage? {
var image = imageWithRenderingMode(.AlwaysTemplate)
UIGraphicsBeginImageContextWithOptions(size, false, scale)
color.set()
image.drawInRect(CGRect(x: 0, y: 0, width: size.width, height: size.height))
image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
In swift 2.0 you can use this
let image = UIImage(named:"your image name")?.imageWithRenderingMode(.AlwaysTemplate)
let yourimageView.tintColor = UIColor.redColor()
yourimageView.image = image
In swift 3.0 you can use this
let image = UIImage(named:"your image name")?.withRenderingMode(.alwaysTemplate)
let yourimageView.tintColor = UIColor.red
yourimageView.image = image
Try something like this
UIImage *originalImage = _sketchImageView.image
UIImage *newImage = [originalImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,50,50)]; // your image size
imageView.tintColor = [UIColor redColor]; // or whatever color that has been selected
imageView.image = newImage;
_sketchImageView.image = imageView.image;
Hope this helps.
In Swift 3.0 you can use this extension: [Based on #VietHung's objective-c solution]
extension UIImage {
func imageWithColor(_ color: UIColor) -> UIImage? {
var image = imageWithRenderingMode(.alwaysTemplate)
UIGraphicsBeginImageContextWithOptions(size, false, scale)
color.set()
image.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
For Swift 3.0, I made a custom subclass of UIImageView called TintedUIImageView. Now the image uses whatever tint color is set in interface builder or code
class TintedUIImageView: UIImageView {
override func awakeFromNib() {
if let image = self.image {
self.image = image.withRenderingMode(.alwaysTemplate)
}
}
}
You can try:
_sketchImageView.image = [self imageNamed:#"imageName" withColor:[UIColor blackColor]];
- (UIImage *)imageNamed:(NSString *)name withColor:(UIColor *)color
{
// load the image
//NSString *name = #"badge.png";
UIImage *img = [UIImage imageNamed:name];
// begin a new image context, to draw our colored image onto
UIGraphicsBeginImageContext(img.size);
// get a reference to that context we created
CGContextRef context = UIGraphicsGetCurrentContext();
// set the fill color
[color setFill];
// translate/flip the graphics context (for transforming from CG* coords to UI* coords
CGContextTranslateCTM(context, 0, img.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// set the blend mode to color burn, and the original image
CGContextSetBlendMode(context, kCGBlendModeColorBurn);
CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height);
CGContextDrawImage(context, rect, img.CGImage);
// set a mask that matches the shape of the image, then draw (color burn) a colored rectangle
CGContextClipToMask(context, rect, img.CGImage);
CGContextAddRect(context, rect);
CGContextDrawPath(context,kCGPathFill);
// generate a new UIImage from the graphics context we drew onto
UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//return the color-burned image
return coloredImg;
}
Try setting the tint color on the superview of the image view. E.g. [self.view setTintColor:color];
in Swift 4 you can simply make an extension like that:
import UIKit
extension UIImageView {
func tintImageColor(color: UIColor) {
guard let image = image else { return }
self.image = image.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
self.tintColor = color
}
}
- SWIFT 4
extension UIImage {
func imageWithColor(_ color: UIColor) -> UIImage? {
var image: UIImage? = withRenderingMode(.alwaysTemplate)
UIGraphicsBeginImageContextWithOptions(size, false, scale)
color.set()
image?.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
Here's how I apply and use tints in IOS 9 with Swift.
//apply a color to an image
//ref - http://stackoverflow.com/questions/28427935/how-can-i-change-image-tintcolor
//ref - https://www.captechconsulting.com/blogs/ios-7-tutorial-series-tint-color-and-easy-app-theming
func getTintedImage() -> UIImageView {
var image : UIImage;
var imageView : UIImageView;
image = UIImage(named: "someAsset")!;
let size : CGSize = image.size;
let frame : CGRect = CGRectMake((UIScreen.mainScreen().bounds.width-86)/2, 600, size.width, size.height);
let redCover : UIView = UIView(frame: frame);
redCover.backgroundColor = UIColor.redColor();
redCover.layer.opacity = 0.75;
imageView = UIImageView();
imageView.image = image.imageWithRenderingMode(UIImageRenderingMode.Automatic);
imageView.addSubview(redCover);
return imageView;
}
One thing you can do is, just add your images to Assets folder in XCode and then change the rendering mode to Template Image, so whenever you change the tint color of UIImageView, it will automatically makes change to image.
Check this link out -> https://www.google.co.in/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&cad=rja&uact=8&ved=0ahUKEwiM0YXO0ejTAhUIQ48KHfGpBpgQjRwIBw&url=https%3A%2F%2Fkrakendev.io%2Fblog%2F4-xcode-asset-catalog-secrets-you-need-to-know&psig=AFQjCNGnAzVn92pCqM8612o1R0J9q1y7cw&ust=1494619445516498
let image = UIImage(named: "i m a g e n a m e")?.withRenderingMode(.alwaysTemplate)
imageView.tintColor = UIColor.white // Change to require color
imageView.image = image
Try this
iOS 13.4 and above
UIImage *image = [UIImage imageNamed:#"placeHolderIcon"];
[image imageWithTintColor:[UIColor whiteColor] renderingMode: UIImageRenderingModeAlwaysTemplate];

Change only one specific UITabBarItem tint color

It is well known that the tint color of selected (or active) items in a UITabBarController can be easily changed, here is an example:
myBarController.tabBar.tintColor = [UIColor redColor];
In this instance, any tab bar item in tabBar will have a red tint once it is made active. Again, this applies to all of the items in this tab bar.
How can the active tint color be different between other tab bar items in the same bar? For example, one item might have a red tint while selected, while another might have a blue tint.
I am aware that this can probably be solved by redrawing and subclassing the entire tab bar. However, this is the only change I need, and it seems overkill to do so. I'm not trying to change the style or how the items are rendered in any way, just to make that style different between different items.
I haven't seen any answers to this question anywhere that are relevant to the updates in iOS 7 and 8.
There is a much easier way to do this!
Add this to the ViewController which UITabBar Item should be in another color
- (void) viewWillAppear:(BOOL)animated {
// change tint color to red
[self.tabBarController.tabBar setTintColor:[UIColor redColor]];
[super viewWillAppear: animated];
}
Insert this to the other ViewControllers
- (void) viewWillAppear:(BOOL)animated {
// change tint color to black
[self.tabBarController.tabBar setTintColor:[UIColor blackColor]];
[super viewWillAppear: animated];
}
I use this to get different Tint colors in each ViewController
e.g.: [ red | black | green | pink ]
#element119 solution using swift(for you lazy guys):
extension UIImage {
func tabBarImageWithCustomTint(tintColor: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
let context: CGContextRef = UIGraphicsGetCurrentContext()
CGContextTranslateCTM(context, 0, self.size.height)
CGContextScaleCTM(context, 1.0, -1.0)
CGContextSetBlendMode(context, kCGBlendModeNormal)
let rect: CGRect = CGRectMake(0, 0, self.size.width, self.size.height)
CGContextClipToMask(context, rect, self.CGImage)
tintColor.setFill()
CGContextFillRect(context, rect)
var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
newImage = newImage.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
return newImage
}
}
I'm using this code to tint my middle icon red:
if let items = self.tabBar.items as? [UITabBarItem] {
let button = items[1]
button.image = button.image?.tabBarImageWithCustomTint(UIColor.redColor())
}
I did some experimenting and based on this answer, found a way to do what I want without subclassing UITabBarItem or UITabBar!
Basically, the idea is to create a method of UIImage that mimics the tint mask behavior of UITabBar, while rendering it in its "original" form and avoiding the native tint mask.
All you have to do is create a new instance method of UIImage that returns an image masked with the color we want:
#interface UIImage(Overlay)
- (instancetype)tabBarImageWithCustomTint:(UIColor *)tintColor;
#end
#implementation UIImage(Overlay)
- (instancetype)tabBarImageWithCustomTint:(UIColor *)tintColor
{
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, self.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
CGContextClipToMask(context, rect, self.CGImage);
[tintColor setFill];
CGContextFillRect(context, rect);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
newImage = [newImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
return newImage;
}
#end
This is a fairly straightforward version of the code in the answer that I posted, with one exception- the returned image has its rendering mode set to always original, which makes sure that the default UITabBar mask won't be applied. Now, all that is needed is to use this method when editing the tab bar item:
navController.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"title" image:normal_image selectedImage:[selected_image tabBarImageWithCustomTint:[UIColor redColor]]];
Needless to say, selected_image is the normal image one gets from UIImage imageNamed: and the [UIColor redColor can be replaced with any color one desires.
This worked fine for me!! code for Swift 3
extension UIImage {
func tabBarImageWithCustomTint(tintColor: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
let context: CGContext = UIGraphicsGetCurrentContext()!
context.translateBy(x: 0, y: self.size.height)
context.scaleBy(x: 1.0, y: -1.0)
context.setBlendMode(CGBlendMode(rawValue: 1)!)
let rect: CGRect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
context.clip(to: rect, mask: self.cgImage!)
tintColor.setFill()
context.fill(rect)
var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
newImage = newImage.withRenderingMode(UIImageRenderingMode.alwaysOriginal)
return newImage
}
}
and after...
button.image = button.image?.tabBarImageWithCustomTint(tintColor: UIColor(red: 30.0/255.0, green: 33.0/255.0, blue: 108.0/255.0, alpha: 1.0))
thanks ;))
swift xcode7.1 tested :
extension UIImage {
func tabBarImageWithCustomTint(tintColor: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
let context: CGContextRef = UIGraphicsGetCurrentContext()!
CGContextTranslateCTM(context, 0, self.size.height)
CGContextScaleCTM(context, 1.0, -1.0)
CGContextSetBlendMode(context, CGBlendMode.Normal)
let rect: CGRect = CGRectMake(0, 0, self.size.width, self.size.height)
CGContextClipToMask(context, rect, self.CGImage)
tintColor.setFill()
CGContextFillRect(context, rect)
var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
newImage = newImage.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
return newImage
}
}
fixed the compatibility bug in #Binsh answer
Swift 5:
extension UIImage {
func tintWithColor(color: UIColor) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
context.scaleBy(x: 1.0, y: -1.0)
context.translateBy(x: 0.0, y: -self.size.height)
context.setBlendMode(.multiply)
let rect = CGRect(origin: .zero, size: size)
guard let cgImage = self.cgImage else { return nil }
context.clip(to: rect, mask: cgImage)
color.setFill()
context.fill(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}

How to create a black UIImage?

I've looked around everywhere, but I can't find a way to do this. I need to create a black UIImage of a certain width and height (The width and height change, so I can't just create a black box and then load it into a UIImage). Is there some way to make a CGRect and then convert it to a UIImage? Or is there some other way to make a simple black box?
Depending on your situation, you could probably just use a UIView with its backgroundColor set to [UIColor blackColor]. Also, if the image is solidly-colored, you don't need an image that's actually the dimensions you want to display it at; you can just scale a 1x1 pixel image to fill the necessary space (e.g., by setting the contentMode of a UIImageView to UIViewContentModeScaleToFill).
Having said that, it may be instructive to see how to actually generate such an image:
Objective-C
CGSize imageSize = CGSizeMake(64, 64);
UIColor *fillColor = [UIColor blackColor];
UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
[fillColor setFill];
CGContextFillRect(context, CGRectMake(0, 0, imageSize.width, imageSize.height));
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Swift
let imageSize = CGSize(width: 420, height: 120)
let color: UIColor = .black
UIGraphicsBeginImageContextWithOptions(imageSize, true, 0)
let context = UIGraphicsGetCurrentContext()!
color.setFill()
context.fill(CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height))
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
UIGraphicsBeginImageContextWithOptions(CGSizeMake(w,h), NO, 0);
UIBezierPath* p =
[UIBezierPath bezierPathWithRect:CGRectMake(0,0,w,h)];
[[UIColor blackColor] setFill];
[p fill];
UIImage* im = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Now im is the image.
That code comes almost unchanged from this section of my book: http://www.apeth.com/iOSBook/ch15.html#_graphics_contexts
Swift 3:
func uiImage(from color:UIColor?, size:CGSize) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, true, 0)
defer {
UIGraphicsEndImageContext()
}
let context = UIGraphicsGetCurrentContext()
color?.setFill()
context?.fill(CGRect.init(x: 0, y: 0, width: size.width, height: size.height))
return UIGraphicsGetImageFromCurrentImageContext()
}
Like this
let image = UIGraphicsImageRenderer(size: bounds.size).image { _ in
UIColor.black.setFill()
UIRectFill(bounds)
}
As quoted in this WWDC vid
There's another function that's older; UIGraphicsBeginImageContext. But please, don't use that.
Here is an example that creates a black UIImage that is 1920x1080 by creating it from a CGImage created from a CIImage:
let frame = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: 1920, height: 1080))
let cgImage = CIContext().createCGImage(CIImage(color: .black()), from: frame)!
let uiImage = UIImage(cgImage: cgImage)

How to create a colored 1x1 UIImage on the iPhone dynamically?

I would like to create a 1x1 UIImage dynamically based on a UIColor.
I suspect this can quickly be done with Quartz2d, and I'm poring over the documentation trying to get a grasp of the fundamentals. However, it looks like there are a lot of potential pitfalls: not identifying the numbers of bits and bytes per things correctly, not specifying the right flags, not releasing unused data, etc.
How can this be safely done with Quartz 2d (or another simpler way)?
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;
}
Here's another option based on Matt Stephen's code. It creates a resizable solid color image such that you could reuse it or change it's size (e.g. use it for a background).
+ (UIImage *)prefix_resizeableImageWithColor:(UIColor *)color {
CGRect rect = CGRectMake(0.0f, 0.0f, 3.0f, 3.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(1, 1, 1, 1)];
return image;
}
Put it in a UIImage category and change the prefix.
I used Matt Steven's answer many times so made a category for it:
#interface UIImage (mxcl)
+ (UIImage *)squareImageWithColor:(UIColor *)color dimension:(int)dimension;
#end
#implementation UIImage (mxcl)
+ (UIImage *)squareImageWithColor:(UIColor *)color dimension:(int)dimension {
CGRect rect = CGRectMake(0, 0, dimension, dimension);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
#end
Using Apple's latest UIGraphicsImageRenderer the code is pretty small:
import UIKit
extension UIImage {
static func from(color: UIColor) -> UIImage {
let size = CGSize(width: 1, height: 1)
return UIGraphicsImageRenderer(size: size).image(actions: { (context) in
context.cgContext.setFillColor(color.cgColor)
context.fill(.init(origin: .zero, size: size))
})
}
}
To me, a convenience init feels neater in Swift.
extension UIImage {
convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
UIGraphicsBeginImageContext(rect.size)
guard let context = UIGraphicsGetCurrentContext() else {
return nil
}
context.setFillColor(color.cgColor)
context.fill(rect)
guard let image = context.makeImage() else {
return nil
}
UIGraphicsEndImageContext()
self.init(cgImage: image)
}
}
Ok, this won't be exactly what you want, but this code will draw a line. You can adapt it to make a point. Or at least get a little info from it.
Making the image 1x1 seems a little weird. Strokes ride the line, so a stroke of width 1.0 at 0.5 should work. Just play around.
- (void)drawLine{
UIGraphicsBeginImageContext(CGSizeMake(320,300));
CGContextRef ctx = UIGraphicsGetCurrentContext();
float x = 0;
float xEnd = 320;
float y = 300;
CGContextClearRect(ctx, CGRectMake(5, 45, 320, 300));
CGContextSetGrayStrokeColor(ctx, 1.0, 1.0);
CGContextSetLineWidth(ctx, 1);
CGPoint line[2] = { CGPointMake(x,y), CGPointMake(xEnd, y) };
CGContextStrokeLineSegments(ctx, line, 2);
UIImage *theImage=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}

Resources