# “Boundary” thickness in HighlightImage

Bug introduced in 11 or earlier and persisting through 11.3

CASE:4076121

I'm having a hard time to understand how I can use HighlightImage and only draw the boundary of a binary image with a thickness of exactly one pixel. The documentation suggests that I can use

HighlightImage[
img,
{{"Boundary", thickness}, Binarize[img]}
]


but that doesn't work properly. Here is a small example that shows the behavior on Mathematica 11.3 on OS X

img = Import["http://i.stack.imgur.com/DLGJC.png"];
Manipulate[
With[{img = ImageResize[img, size]},
Show[HighlightImage[
img,
{{"Boundary", thickness}, Binarize[img]}
], ImageSize -> 1024
]
], {size, 100, 500, 1}, {thickness, .1, 10}
]


As you will see, the thickness setting has no influence and if you scale the image up with the size slider, then the boundary thickness covers many pixels

• I noticed this too, but didn't complain to WRI. It changed in some recent version. It seemed intentional ... – Szabolcs Jun 6 '18 at 14:05
• @Szabolcs It seems like they broke this functionality when refactoring the code (see my answer below) - no idea why they did it in the first place though – Lukas Lang Jun 6 '18 at 14:11
• @Szabolcs always complain. It may get fixed )) – Batracos Jun 19 '18 at 18:38
• @LukasLang it is indeed a bug that slipped through the testing. I just committed a fix. As you where wondering, the reason is that directives like "Boundary" should change the behaviour of all the subsequent primitives, resetting other custom scopes like "Blur". – Batracos Jun 19 '18 at 18:43
• @Batracos That's great to hear! Regarding the reasoning: Thanks for the insight. I was also wondering why some definitions are only loaded by toGraphicsPrimitiveDefinitions - is this something entirely related to other internals or is there some reason behind it that could also be relevant for custom code? – Lukas Lang Jun 19 '18 at 18:49

The following fixes the issue:

If[\$VersionNumber>=11.3,
Begin["ImageInteractiveDump"],
Begin["ImageColorOperationsDump"]
];
HighlightImage;
DownValues[toGraphicsPrimitive] = DownValues[toGraphicsPrimitive] /.
{HoldPattern[pre_; Sequence[s__]] :> ((pre; {s}) /. {res__} :> res)};
End[];


### Why does this work

It appears that at some point, every definition of ImageInteractiveDumptoGraphicsPrimitive (toGP in the following) was prepended with toGraphicsPrimitiveDefinitions (so toGP[args]:=rhs became toGP[args]:=(toGPD;rhs)). It looks like this loads some more definitions for toGP, but no idea what the purpose of doing it this way is...

The issue is that the signature of toGP that handles {"Boundary", thickness_} returned a Sequence, which is evaluated prematurely by the CompoundExpression that got wrapped around. The above fix resolves this issue by only introducing the Sequence head after the CompundExpression is done evaluating. (please leave a comment if you find a more straightforward solution to protect the Sequence head)

• Thanks for spelunking for me. I was really worried I simply use it wrong somehow. I'm looking at it in detail later. +1 – halirutan Jun 6 '18 at 15:09
• @Mathe172 - Please how to use the fix, where to put the Begin-End sequence? Is it a procedure, shall I call it before HighligtImage? Thanks in advance – CJoe Jun 10 '18 at 13:33
• @CJoe Yes, just execute it once before you call HighlightImage. For example, you can add it as first line to your notebook – Lukas Lang Jun 10 '18 at 13:36
• @Mathe172 - Im sorry, I cant make it working. Either it does not have influence or the Mathematica crashes (on Pi3). Would you be so kind and put the working code of that your example above? – CJoe Jun 10 '18 at 15:43
• A simpler fix that however requires changing existing code is to use ... , FaceForm[], EdgeForm[AbsoluteThickness[n]], ... in place of {"Boundary", n}`. – Batracos Jun 19 '18 at 18:50