6

The following code uses Graphics to display text "Mathematica" of pure red color on white background.

Then it displays all colors used in the rasterized version of the graphics.

Due to anti-aliasing we are of course expecting to have more colors than just pure red and pure white ones.

But why all different shades/tints of yellow, orange, pink, violet and brown???

I would expect to have just tints of red that are present in blending between red color (of text) and white color (of background) as we can see in third image.

gr = Graphics[{Text[
     Style["Mathematica", RGBColor[1, 0, 0], Italic, 30], {0, 0}]}, 
   PlotRange -> {-1/4, 1/4}] // Rasterize
colors = Flatten[ImageData[gr, "Byte"], 1] // DeleteDuplicates;
Graphics[Table[{RGBColor @@ (colors[[x]]/255), Disk[{8 x/10, 0}]}, {x,
    1, Length[colors]}], ImageSize -> {Automatic, 100}, 
 Background -> Black]
Graphics[Table[{Blend[{Red, White}, x], Disk[{8 x, 0}]}, {x, 0, 1, 
   1/10}], ImageSize -> {Automatic, 100}, Background -> Black]
Clear[gr, colors]

enter image description here enter image description here enter image description here

Is it a correct behavior or a bug?

azerbajdzan
  • 15,863
  • 1
  • 16
  • 48
  • That's expected behaviour for text / font-rendering and hinting, see here: https://en.wikipedia.org/wiki/Subpixel_rendering . It does not occur with non-text things like lines / points / shapes etc. Try using black for the font colour and you'll see all sorts of colours appearing that look like this https://upload.wikimedia.org/wikipedia/commons/f/f3/Subpixel_e.png – flinty Sep 06 '20 at 16:56
  • Can I am convert the text to something that would Mathematica treat as if were lines, polygons, circles...? – azerbajdzan Sep 06 '20 at 17:00
  • It's not just Mathematica - here's a zoom-in of some of the text from this question, as seen in my browser: https://i.imgur.com/sIyISmt.png – Carmeister Sep 07 '20 at 20:21

2 Answers2

7

As explained in the comments, text rendering is special and has sub-pixel anti-aliasing which introduces the colours. This does not occur with other graphics primitives like lines, circles, polygons etc. just text.

ImageResize[Rasterize[Text["Hello"], RasterSize -> 16], 100, 
 Resampling -> "Nearest"]

subpixel text

ImageResize[
 Rasterize[Graphics[Line[{{0, 0}, {1, Sqrt[2]}}]], 
  RasterSize -> 16], 100, Resampling -> "Nearest"]

no subpixel line

I don't know how to turn off the subpixel anti-aliasing but this work-around can turn the text into a mesh which will then render without the subpixel anti-aliasing colours appearing:

mesh = ImageMesh[
  ColorNegate@
   Rasterize[
    Graphics[
     Text[Style["Mathematica", RGBColor[0, 0, 0], Italic, 30]]], 
    RasterSize -> 1500]]

gr = Style[Graphics[{EdgeForm[None], FaceForm[Red], mesh}], Antialiasing -> True] // Rasterize colors = Flatten[ImageData[gr], 1] // DeleteDuplicates; Graphics[MapIndexed[{RGBColor @@ #1, Disk[{8 First[#2]/10, 0}]} &, colors], ImageSize -> {Automatic, 100}, Background -> Black] Graphics[Table[{Blend[{Red, White}, x], Disk[{8 x, 0}]}, {x, 0, 1, 1/10}], ImageSize -> {Automatic, 100}, Background -> Black]

enter image description here

no subpixel Mathematica text


Another trick you can use is to export it as SVG then re-import it using ResourceFunction["SVGImport"]. This has the effect of breaking the text down into FilledCurve primitives which will not render with subpixel anti-aliasing:

svgtricktext = 
 ResourceFunction["SVGImport"][
  ExportString[Text[Style["Hello", Red]], "SVG"]]

I've been searching around and apparently there's this trick where you can set the opacity to 0.999 and it either triggers greyscale sub-pixel rendering or turns it off instead of doing RGB subpixel rendering. See here, and here

Rasterize[Style["Hello", Red, FontOpacity -> .999], RasterSize -> 32]
flinty
  • 25,147
  • 2
  • 20
  • 86
7

Another standard way:

graphicsText[x_] := ImportString[ExportString[x, "PDF"], "PDF"][[1, 1]];
gr = Graphics@ graphicsText[
   Text[Style["Mathematica", RGBColor[1, 0, 0], Italic, 30]]]
colors = Flatten[ImageData[gr, "Byte"], 1] // DeleteDuplicates;
Graphics[Table[{RGBColor @@ (colors[[x]]/255), 
   Disk[{8 Mod[x, 40]/10, -2 Floor[x/40]}]}, {x, 1, Length[colors]}], 
 ImageSize -> 400, Background -> Black]
Graphics[Table[{Blend[{Red, White}, x], Disk[{8 x, 0}]}, {x, 0, 1, 
   1/10}], ImageSize -> 400, Background -> Black]

enter image description here

Michael E2
  • 235,386
  • 17
  • 334
  • 747