Mac / Windows Color Inconsistencies

I have created a custom toolbar using a canvas and png images for the buttons. I use the background color in the button images (RGB value) to set the background of the canvas to match and everything works fine on Windows. But now I’ve moved over to the Mac the specified background color which is a constant RGB(110, 110, 110) is now rendered as RGB(129, 129, 129). This means the toolbar background does not match the background of the toolbar button icons and looks very bad.

This makes no sense to me. I have specified a color constant and OS X is essentially just deciding to display a different color grey.

Why is this and is there a way around to ensure colors always match?

Note: I have determined the RGB color value of the images (to use as the canvas background color) using Photoshop color picker.

The colors you specify on macOS are in generic color space and later mapped by colorcync to display.

In MBS Plugin we have a lot of functions related to color management which can help here.

Hi Christian. I didn’t really want to have to use a plugin but will if necessary so could you please point me to the plugin and method you mean and if possible give me a code example of how to do this?

What do you want exactly?
Calculate which color value to use to get the desired color on screen?

Yes, I think so. My image background colour is RGB(110, 110, 110) and so I need the canvas background colour behind it to exactly match that (so the user sees no edge to the image) but right now on Mac if I define the RGB colour as above Xojo/Cocoa makes it lighter with RGB(129, 129, 129) and so the image background is seen against the canvas background rather than being part of it.

try this:

[code]dim screen as NSScreenMBS = NSScreenMBS.mainScreen
dim screenColorSpace as NSColorSpaceMBS = screen.colorSpace
'dim genericColorSpace as NSColorSpaceMBS = NSColorSpaceMBS.genericRGBColorSpace
'dim windowcolorSpace as NSColorSpaceMBS = self.NSWindowMBS.colorSpace

dim InputColor as color = rgb(110,110,110)
dim InputNSColor as new NSColorMBS(InputColor)
'dim InputNSColorSpace as NSColorSpaceMBS = InputNSColor.colorSpace

dim OutputNSColor as NSColorMBS = InputNSColor.colorUsingColorSpace(screenColorSpace)
dim OutputColor as color = OutputNSColor.colorValue

Break[/code]

You need MBS Plugins Main and CocoaBase at least.

Denise, you may want to measure the color you need in the picture on the Mac itself, not on Photoshop, because Mac applies a color profile to both controls color and pictures. Which explains why you get different results.

To make matters even more difficult, the user can change that color profile in the Display settings, so you cannot count on it to be the same for all machines.

I would suggest you get the color of the pixels in the picture you want to match in the software itself, via an RGBSurface for instance. Then you can apply exactly the same color to your background.

[quote=322829:@Christian Schmitz]try this:

[code]dim screen as NSScreenMBS = NSScreenMBS.mainScreen
dim screenColorSpace as NSColorSpaceMBS = screen.colorSpace
'dim genericColorSpace as NSColorSpaceMBS = NSColorSpaceMBS.genericRGBColorSpace
'dim windowcolorSpace as NSColorSpaceMBS = self.NSWindowMBS.colorSpace

dim InputColor as color = rgb(110,110,110)
dim InputNSColor as new NSColorMBS(InputColor)
'dim InputNSColorSpace as NSColorSpaceMBS = InputNSColor.colorSpace

dim OutputNSColor as NSColorMBS = InputNSColor.colorUsingColorSpace(screenColorSpace)
dim OutputColor as color = OutputNSColor.colorValue

Break[/code]

You need MBS Plugins Main and CocoaBase at least.[/quote]
Thanks Christian but it doesn’t seem to work. The output color is not the right grey and I’ve tried various colorspace options in the InputNSColor.colorUsingColorSpace call.

[quote=322830:@Michel Bujardet]Denise, you may want to measure the color you need in the picture on the Mac itself, not on Photoshop, because Mac applies a color profile to both controls color and pictures. Which explains why you get different results.

To make matters even more difficult, the user can change that color profile in the Display settings, so you cannot count on it to be the same for all machines.

I would suggest you get the color of the pixels in the picture you want to match in the software itself, via an RGBSurface for instance. Then you can apply exactly the same color to your background.[/quote]
Thanks, Michel. Yes, I see what you mean. I think I will investigate that also.

Well I just used the code below and it returns the same incorrect gray color:

Dim surf As RGBSurface = p.RGBSurface Dim c As Color = surf.Pixel(0, 0)

It may be worthwhile trying a jpeg version instead of png - I’ve seen a few weird things happen with png files. Just make sure to deselect Embed Color Profile - and use the highest quality settings.

Thanks Steve but unfortunately that did not work.

I would suggest making the PNG images transparent; so they have no background, this way the actual color displayed behind them is irrelevant.

Out of curiosity; why are you creating your own toolbar?

PNG would be good indeed. And one with color profile in file.

try this:

[code]dim screen as NSScreenMBS = NSScreenMBS.mainScreen
dim screenColorSpace as NSColorSpaceMBS = screen.colorSpace
dim genericColorSpace as NSColorSpaceMBS = NSColorSpaceMBS.genericRGBColorSpace
'dim windowcolorSpace as NSColorSpaceMBS = self.NSWindowMBS.colorSpace

// build color in screen color space
dim InputColor as color = rgb(110,110,110)
dim Components() as Double = array(InputColor.Red / 255.0, InputColor.Green / 255.0, InputColor.Blue / 255.0, 1.0)
dim InputNSColor as NSColorMBS = NSColorMBS.colorWithColorSpace(screenColorSpace, Components)
'dim InputNSColorSpace as NSColorSpaceMBS = InputNSColor.colorSpace

// convert to generic
dim OutputNSColor as NSColorMBS = InputNSColor.colorUsingColorSpace(genericColorSpace)
dim OutputColor as color = OutputNSColor.colorValue

// convert to screen
dim ScreenNSColor as NSColorMBS = InputNSColor.colorUsingColorSpace(screenColorSpace)
dim ScreenColor as color = ScreenNSColor.colorValue

Break[/code]

The code above did convert in wrong direction. This now converts from screen space back to generic and forward to screen.

[quote=322893:@Christian Schmitz]try this:

[code]dim screen as NSScreenMBS = NSScreenMBS.mainScreen
dim screenColorSpace as NSColorSpaceMBS = screen.colorSpace
dim genericColorSpace as NSColorSpaceMBS = NSColorSpaceMBS.genericRGBColorSpace
'dim windowcolorSpace as NSColorSpaceMBS = self.NSWindowMBS.colorSpace

// build color in screen color space
dim InputColor as color = rgb(110,110,110)
dim Components() as Double = array(InputColor.Red / 255.0, InputColor.Green / 255.0, InputColor.Blue / 255.0, 1.0)
dim InputNSColor as NSColorMBS = NSColorMBS.colorWithColorSpace(screenColorSpace, Components)
'dim InputNSColorSpace as NSColorSpaceMBS = InputNSColor.colorSpace

// convert to generic
dim OutputNSColor as NSColorMBS = InputNSColor.colorUsingColorSpace(genericColorSpace)
dim OutputColor as color = OutputNSColor.colorValue

// convert to screen
dim ScreenNSColor as NSColorMBS = InputNSColor.colorUsingColorSpace(screenColorSpace)
dim ScreenColor as color = ScreenNSColor.colorValue

Break[/code]

The code above did convert in wrong direction. This now converts from screen space back to generic and forward to screen.[/quote]
Thanks, Christian. " convert to generic " works and returns RGB(90,90,90) which when filling a rectangle on screen displays as the equivalent of RGB(110, 110, 110) and matches the image file.

Yes I did think about doing that and have for some images and it will work in some instances but not in all and also will not work for other custom controls which need to match left and right edge images that just look better as images and not being drawn in code.

I have made my own toolbar because it looks much better than anything else available and is more functionally for my needs :slight_smile:

Great to hear it works.

[quote=322841:@Denise Adams]Well I just used the code below and it returns the same incorrect gray color:

Dim surf As RGBSurface = p.RGBSurface Dim c As Color = surf.Pixel(0, 0)[/quote]

That is expected. macOS applies the color profile to loaded pictures. It is not an “incorrect” color, it is the way the system renders all pictures.

If you want the background to be of the same color, simply use that value.

The pixel color from the picture is technically correct as RGB(110,110,110) but you can’t use that color to FillRect() because it displays as RGB(129,129,129) even though the picture gray displays as RGB(110,110,110). So the pixel method is great to ensure you have the correct background color to use but you still have to convert it using Christian’s method before setting Graphics.ForeColor.

The picture has a colorspace assigned, so the colors are matched to the colorspace of the window.
But in Xojo you draw in generic RGB and the window buffer than receives the color after converting.

Thanks for explaining.