5

Suppose I have a plot with a transparent background and I want to place a letter right on top of a curve. For clarity, I'd like to add an outline around the letter. The image below shows a white outline, but I want the outline to match the transparent background. How can that be accomplished? In other words, is there a way to "paint" with transparency, i.e. to "erase"?

enter image description here

Wynne
  • 1,526
  • 9
  • 14

2 Answers2

3

Maybe you can use Region functionality to erase portions of the primitives, although it may be slow. Here is some code that does this:

ErasePrimitives[prims_, region_] := prims /. r_?RegionQ :> erasePrimitive[r, region]

erasePrimitive[p:Polygon[{__?MatrixQ}], region_] := ErasePrimitives[Thread[p], region]

erasePrimitive[prim_, region_] := Which[ RegionDisjoint[region, prim], prim,

RegionWithin[region, prim], 
Nothing,

True, 
Replace[
    RegionDifference[prim, region], 
    b_BooleanRegion :> DiscretizeRegion[b, MeshCellStyle->{0->None}]
]

]

Example graphic:

prim = {Disk[{.5,.1},.2], Line[{{-1,0},{1,0}}], Line[{{0,-1},{0,1}}]};
Graphics[prim]

enter image description here

Erase some portions, and add text:

erased = ErasePrimitives[prim, RegionUnion[Disk[{0, 0}, .1], Disk[{.5, 0}, .2]]];
Graphics[
    {
    erased,
    Text[Style["A", 24], {0, 0}],
    Text[Style["C", 48], {.5, 0}]
    },
    Background->LightBlue
]

enter image description here

Carl Woll
  • 130,679
  • 6
  • 243
  • 355
  • This is great, Carl! I think that this gives more than enough to be customizable by the OP to do precisely what they want to do. I think it is not too complicated to turn the lettering into a region (as I have seen this before with a 3D billboard here, iirc) and take only the border/outline as one sees fit to use, and apply this ErasePrimitives function! – CA Trevillian Aug 26 '21 at 04:19
2

The core idea is to use white throughout and then replace all the white with a transparent color.

myA = Graphics[{Thickness[0.02], Line[{{0, 0}, {1, 0}}],
      Text[Style["A", 24, Background -> White], {.5, 0}]},
      PlotRange -> {{0, 1}, {-.2, .2}}];

final = ColorReplace[myA, White -> Directive[Opacity[0], White]];

Show[ExampleData[{"TestImage", "House"}], final]

line, A on transparent background atop photo

David G. Stork
  • 41,180
  • 3
  • 34
  • 96
  • Will this preserve the vector quality of the plot? – Wynne Aug 25 '21 at 23:24
  • 1
    Alas, no it won't. The best way forward, then, is to manually crop the obscured lines (draw two half-lines with a split), and use Background ->Directive[Opacity[0], White] for the text. OR... make everything very high resolution. – David G. Stork Aug 25 '21 at 23:29