17

I have a NSPopUpButton which contains a list of colors. In front of the color title, I need to display a small box of the same color (maybe an image of same color). So, I was thinking that if I can create an NSImage using NSColor (which will be already present), then I can use the -[NSMenuItem setImage:] method to display the image in front of the color title in the popup button.

So, how can I create an NSImage using NSColor?

Any other approaches to solve the problem are also welcome. :)

Ky -
  • 30,724
  • 51
  • 192
  • 308
rsharma
  • 612
  • 6
  • 20
  • This should be what you are looking for: [http://stackoverflow.com/questions/990976/how-to-create-a-colored-1x1-uiimage-on-the-iphone-dynamically][1] [1]: http://stackoverflow.com/questions/990976/how-to-create-a-colored-1x1-uiimage-on-the-iphone-dynamically – Weichen Wang Jun 27 '12 at 10:39

4 Answers4

19

A simple category method will do this

@interface NSImage (ImageAdditions)

+(NSImage *)swatchWithColor:(NSColor *)color size:(NSSize)size;


@end

@implementation NSImage (ImageAdditions)

+(NSImage *)swatchWithColor:(NSColor *)color size:(NSSize)size
{
    NSImage *image = [[[NSImage alloc] initWithSize:size] autorelease];
    [image lockFocus];
    [color drawSwatchInRect:NSMakeRect(0, 0, size.width, size.height)];
    [image unlockFocus];
   return image;    
}

@end

[EDIT] remove deprecated API

Warren Burton
  • 17,451
  • 3
  • 53
  • 73
  • `– setScalesWhenResized:` is **deprecated**. *This method was related to caching behavior. In Mac OS X v10.6 and later image caching is no longer necessary and as a result there is no replacement necessary.* – Justin Boo Jun 27 '12 at 18:35
14

If you're using AppKit, here's a Swift 5 convenience initializer version of the other answers. Sadly, this doesn't work in UIKit

extension NSImage {
    convenience init(color: NSColor, size: NSSize) {
        self.init(size: size)
        lockFocus()
        color.drawSwatch(in: NSRect(origin: .zero, size: size))
        unlockFocus()
    }
}

Usage example:

let redSwatchImage = NSImage(color: .red, size: NSSize(width: 128, height: 128))

Feel free to change the semantics as necessary

Ky -
  • 30,724
  • 51
  • 192
  • 308
7

And the swift extension variant of above:

import Cocoa

extension NSImage {
  class func swatchWithColor(color: NSColor, size: NSSize) -> NSImage {
    let image = NSImage(size: size)
    image.lockFocus()
    color.drawSwatchInRect(NSRect(origin: .zero, size: size))
    image.unlockFocus()
    return image
  }
}
Ky -
  • 30,724
  • 51
  • 192
  • 308
M0rph3v5
  • 945
  • 1
  • 11
  • 23
0

I've wanted to do this so much that I made a little Swift package for it: Swift Color Swatches.

It's used like this:

import ColorSwatches

// If you prefer to use a factory initializer on the image type:
let nsImagePurple1 = NSImage.swatch(color: .systemPurple)
let uiImagePurple1 = UIImage.swatch(color: .systemPurple)

// If you prefer to use an instance method on a color instance:
let nsImagePurple2 = NSColor.systemPurple.swatch()
let uiImagePurple2 = UIColor.systemPurple.swatch()

You can also pass a size to these if the default doesn't work for you

Ky -
  • 30,724
  • 51
  • 192
  • 308