4
$\begingroup$

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

$\endgroup$
6
  • 2
    $\begingroup$ What's the code you used to generate your figure? Try Graphics[Text[Style["A", Large]], Background -> Transparent, {0, 0}] $\endgroup$
    – Derek H
    Aug 25, 2021 at 12:28
  • $\begingroup$ You'd be better off exporting to photoshop and doing this there - otherwise you'd have to rasterize and use ImageAdd/ImageSubtract. $\endgroup$
    – flinty
    Aug 25, 2021 at 13:46
  • $\begingroup$ @DerekH I need to erase the two lines around the A. $\endgroup$
    – Wynne
    Aug 25, 2021 at 16:23
  • $\begingroup$ "outline around the letter" or border around the letter? $\endgroup$ Aug 25, 2021 at 21:31
  • $\begingroup$ Outline, I think $\endgroup$
    – Wynne
    Aug 26, 2021 at 0:11

2 Answers 2

3
$\begingroup$

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

$\endgroup$
1
  • $\begingroup$ 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! $\endgroup$ Aug 26, 2021 at 4:19
1
$\begingroup$

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

$\endgroup$
2
  • $\begingroup$ Will this preserve the vector quality of the plot? $\endgroup$
    – Wynne
    Aug 25, 2021 at 23:24
  • 1
    $\begingroup$ 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. $\endgroup$ Aug 25, 2021 at 23:29

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.