5
$\begingroup$

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?

$\endgroup$
  • $\begingroup$ That's expected behaviour for text / font-rendering and hinting, see here: 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 upload.wikimedia.org/wikipedia/commons/f/f3/Subpixel_e.png $\endgroup$ – flinty Sep 6 '20 at 16:56
  • $\begingroup$ Can I am convert the text to something that would Mathematica treat as if were lines, polygons, circles...? $\endgroup$ – azerbajdzan Sep 6 '20 at 17:00
  • $\begingroup$ It's not just Mathematica - here's a zoom-in of some of the text from this question, as seen in my browser: i.imgur.com/sIyISmt.png $\endgroup$ – Carmeister Sep 7 '20 at 20:21
7
$\begingroup$

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]
$\endgroup$
7
$\begingroup$

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

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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