5
$\begingroup$

When trying to code complex numbers into colors by e.g. using brightness as absolute value and hue as phase angle of a complex number (see one of the answers to the following question), I stumbled over the following strange behavior of the Graphics directive. When issuing the following command

ImageData[ColorConvert[Graphics[{Hue[0.25,1,0.75],Disk[]},ImageSize->{360, 360}],"HSB"]][[180,180]]

one would expect the result

{0.25,1.,0.75}

however I get

{0.25098,1.,0.74902}

I presume that Graphics does some colorscaling or -correction. However I found no option to e.g. set the white point or do any other color correction in Graphics. I know that the resulting color is potentially just subtilely different from the specified one, but if I would like to use such an image as an input to reconstruct a 2D array of complex numbers, the original data would be significantly distorted.

Any ideas how to influence this behaviour?

$\endgroup$
2
  • $\begingroup$ Related: (7780327) $\endgroup$
    – Mr.Wizard
    Commented Feb 17, 2017 at 7:35
  • $\begingroup$ Proposed duplicate: (17638) $\endgroup$
    – Mr.Wizard
    Commented Feb 17, 2017 at 7:37

2 Answers 2

5
$\begingroup$

Computers (mostly) use 256 discrete values for the RGB components of colours. You are simply seeing

Round[{0.25, 1., 0.75}, 1./255]

Is it possible to use 16-bit colour in Graphics? I don't think so.

You are working both with Graphics and Image. You are implicitly converting the Graphics to an Image using ColorConvert. Image does support higher precision representations, including 16-bit integer, 32-bit float and 64-bit float. See the Details section in Image and ImageType. We could produce a higher precision image by converting explicitly using Image[Graphics[...], "Real"]. However, this still rasterizes the Graphics (vector graphics) at 8-bit colour depth, and then converts the result to 64-bit float. So we don't gain any precision with this approach. The only reason why you will see a different output from your code if you do this is that the colour space conversion will be done at high precision now. However, the starting RGB values will still be only 8-bit.

$\endgroup$
4
  • $\begingroup$ I feel pretty dumb, not noticing the 8 bit issue. Any idea how to convince Graphics to use 16 bit color definitions? $\endgroup$
    – Rainer
    Commented Oct 26, 2016 at 8:57
  • $\begingroup$ @Rainer I updated the answer with what I know. I believe that this is not possible, but of course it's hard to prove a negative ... $\endgroup$
    – Szabolcs
    Commented Oct 26, 2016 at 9:15
  • $\begingroup$ @Rainer I checked that a PDF exported from Mma preserves the all digits in colour specifications (doesn't convert to 8-bit). I think that Ghostscript can rasterize at 16-bit, or at least at 12-bit colour depth. You might want to look this up and try using Ghostscript for rasterization (or any other PDF renderer that can do more than 8 bit). I don't have time to read the GS documentation and find out how to do this right now. $\endgroup$
    – Szabolcs
    Commented Oct 26, 2016 at 9:36
  • $\begingroup$ I linked a proposed duplicate in a comment below the Question. Would you please take a look and tell me if you agree or disagree? $\endgroup$
    – Mr.Wizard
    Commented Feb 17, 2017 at 7:37
1
$\begingroup$

To overcome the issue pointed out by Szabolcs in his answer, with:

out = ImageData[
   ColorConvert[
    Graphics[{Hue[0.25, 1, 0.75], Disk[]}, ImageSize -> {360, 360}], 
    "HSB"]][[180, 180]]

one can do

N @ Rationalize[#, 1/255]& @ out

{0.25, 1., 0.75}

$\endgroup$
1
  • $\begingroup$ Your answer works in the given case. However, for some colors in the LAB color space, it doesn't work perfectly. I can retrieve the L and a component values accurately, but not the b component. See mathematica.stackexchange.com/questions/163579/… $\endgroup$
    – user36426
    Commented Jan 15, 2018 at 10:30

Not the answer you're looking for? Browse other questions tagged or ask your own question.