I use TColor::GetColor
to get custom colours from the HTML RGB code. However, when I then look at the generated PNG and check the colours, they’re not quite right, giving, for example, “#f0f0f0” instead of “#eeeeee”.
Can you provide a small script showing this problem ?
Try this:
TCanvas canv;
TBox box(0.2,0.2,0.8,0.8);
auto color = TColor::GetColor("#eeeeee");
box.SetFillColor(color);
box.Draw();
canv.SaveAs("test.png");
Using a colour picker on the canvas itself, colours are correct. In the PNG, the box colour is “#ececec” (for me, at least).
I see a difference when I look at the png generated in batch mode.
In interactive mode the canvas on screen and the png are the same and R=G=B = 238.
In batch mode I get R=G-B=242 for the png.
In batch mode we use the libafterimage library…right now I have no idea how to fix that.
Sorry, that seems to be a Gwenview bug. Try this instead:
auto color = TColor::GetColor("#eeeeee");
gStyle->SetCanvasColor(color);
TCanvas canv;
Picking the colour off the canvas now gives me #F3F3F3.
if I do that the png file is fine in both cases (242).
But #eeeeee should have a value of 238 for R, G, and B.
On mac when I do this:
auto color = TColor::GetColor("#eeeeee");
gStyle->SetCanvasColor(color);
TCanvas canv;
I get R = G = B = 242 with the Cocoa back end
And R = G = B = 243 with the X11 backend.
(For the TCanvas on screen). I will check.
ROOT does not store the R G B values as integers between 0 and 255 but as float between 0 and 1. What we get here might be a rounding effect. The following macro also give 242;
{
int i = TColor::GetColor("#eeeeee");
TColor *c = gROOT->GetColor(i);
float r = c->GetRed();
printf ("Red value = %g %d\n",r,(int)(r*255));
}
it gives:
root [0] .x color.C
Red value = 0.95 242
It looks like dividing by 255 is a bad way of doing the conversion, because it gives answers that are inexact in binary. Dividing by 256 instead gives 238/256 = 0.9297
, then 0.9297 * 255 = 237
which is much closer than 242.
In other words, GetColor should divide by 256 instead of 255 (special casing 255 -> 1.0).
(int)(r * 255.0 + 0.5)
It needs to convert an int to a float, not the other way around. To divide by 256, it sets the mantissa to the int value, and the exponent to -8.
This issue is not connected to rounding. In GetColor there is a logic to find the closest color. If one is found (within a given threshold) it is used. That’s why we get 242. If I comment this logic I get exactly 238.
It’s probably a good idea to make the threshold configurable then.
This is now implemented in the ROOT master:
$ root
----------------------------------------------------------------
| Welcome to ROOT 6.11/01 http://root.cern.ch |
| (c) 1995-2017, The ROOT Team |
| Built for macosx64 |
| From heads/master@v6-09-02-983-g9f8fdce, May 24 2017, 16:37:13 |
| Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
----------------------------------------------------------------
root [0] int i = TColor::GetColor("#eeeeee");
root [1] TColor *c = gROOT->GetColor(i);
root [2] printf ("%d\n",(int)(c->GetRed()*255));
242
root [3] TColor::SetColorThreshold(0.);
root [4] i = TColor::GetColor("#eeeeee");
root [5] c = gROOT->GetColor(i);
root [6] printf ("%d\n",(int)(c->GetRed()*255));
238
root [7]
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.