Adding Layer Stroke Around Perimiter of Art

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Adding Layer Stroke Around Perimiter of Art

Post by dfelder »

When dealing with an artfile with transparency (PNG, PSD, GIF), is there a way to create a stroke around whatever opaque pixels actually exist?

In other words, is there a way to generate a "Stroke" or "Layer Stroke" just like PhotoShop does it? A 5 pixel black stroke, for example.

I've looked through countless examples here, but everything is creating a stroke around the perimeter an object that's drawn by IM (text, circle, rectangle, etc.). I want take an exisiting file (with some transparent pixels), and then add a stroke to whatever was already there...
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Adding Layer Stroke Around Perimiter of Art

Post by fmw42 »

Extract the alpha channel (which will be white and black -- or if gray threshold it). Then use -edge to draw an edge at the transition. Then use that as both the overlay and mask image to composite it over your original without the transparency. Then add the transparency back.

try the following

white edge:

convert logo: -transparent white logot.png
convert logot.png \
\( -clone 0 -alpha off \) \
\( -clone 0 -alpha extract \) \
\( +clone -edge 1 \) \
\( -clone 1 -clone 3 -clone 3 -compose over -composite \) \
-delete 0,1,3 +swap -compose copy_opacity -composite \
logot_edge_white.png


black edge:

convert logo: -transparent white logot.png
convert logot.png \
\( -clone 0 -alpha off \) \
\( -clone 0 -alpha extract \) \
\( +clone -negate -edge 1 -negate \) \
\( -clone 3 -clone 1 -clone 3 -compose over -composite \) \
-delete 0,1,3 +swap -compose copy_opacity -composite \
logot_edge_black.png
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Re: Adding Layer Stroke Around Perimiter of Art

Post by dfelder »

Thanks for the tip. It seems quite complicated, and it looks like I need to make two images and merge them. I would prefer to leverage a single line because I'm using a DOS command window and the VB module for scripting and I haven't figured out how to integrate the "\" "(" and other characters in these extended operations.

Is there an option with -edge? I'm researching it now.

Or...I could survive with a shadow, glow, or emboss or any other effect that would let me partially see a white image (with transparency) overlayed on a white background.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Adding Layer Stroke Around Perimiter of Art

Post by fmw42 »

For windows differences see http://www.imagemagick.org/Usage/windows/

I am not a windows user, but try this:

#This is just to make the transparent image:
convert logo: -transparent white logot.png

# this is the processing for windows
convert logot.png ^
( -clone 0 -alpha off ) ^
( -clone 0 -alpha extract ) ^
( +clone -edge 1 ) ^
( -clone 1 -clone 3 -clone 3 -compose over -composite ) ^
-delete 0,1,3 +swap -compose copy_opacity -composite ^
logot_edge_white.png

Similarly for the black edge example remove the \ before ( or ) and use ^ in place of \ for line continuation or just make one long line as below for the white edge example

convert logot.png ( -clone 0 -alpha off ) ( -clone 0 -alpha extract ) ( +clone -edge 1 ) ( -clone 1 -clone 3 -clone 3 -compose over -composite ) -delete 0,1,3 +swap -compose copy_opacity -composite logot_edge_white.png

the -edge parameter just makes the edge broader (like strokewidth)
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Re: Adding Layer Stroke Around Perimiter of Art

Post by dfelder »

Indeed, that is exactly what I did (and it errors out for many reasons):

C:\>convert offset.png ( -clone 0 -alpha off ) ( -clone 0 alpha extract ) ( +clo
ne -edge 1 ) ( -clone 1 -clone 3 -clone 3 -compose over -composite ) -delete 0,
1,3 +swap -compose copy_opacity -composite offset1.png

Magick: unable to open image `alpha': No such file or directory @ error/blob.c/O
penBlob/2587.
Magick: no decode delegate for this image format `alpha' @ error/constitute.c/Re
adImage/532.
Magick: unable to open image `extract': No such file or directory @ error/blob.c
/OpenBlob/2587.
Magick: no decode delegate for this image format `extract' @ error/constitute.c/
ReadImage/532.


I have tried changing the spacing, removing the parentheses, etc., to no avail.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Adding Layer Stroke Around Perimiter of Art

Post by fmw42 »

C:\>convert offset.png ( -clone 0 -alpha off ) ( -clone 0 alpha extract ) ( +clo
ne -edge 1 ) ( -clone 1 -clone 3 -clone 3 -compose over -composite ) -delete 0,
1,3 +swap -compose copy_opacity -composite offset1.png
First, you left off a hyphen (minus sign) before alpha in ( -clone 0 -alpha extract )

Second, you may have too old a version of IM to use -alpha. What version of IM are you using?
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Adding Layer Stroke Around Perimiter of Art

Post by anthony »

fmw42 wrote:Extract the alpha channel (which will be white and black -- or if gray threshold it). Then use -edge to draw an edge at the transition. Then use that as both the overlay and mask image to composite it over your original without the transparency. Then add the transparency back.
I would do the same, but use 'EdgeOut' to get an edge OUTSIDE the shape ;-)

Code: Select all

convert  http://www.imagemagick.org/Usage/images/knight.png \
        \(  +clone -alpha extract -morphology EdgeOut Diamond \
            -background red -alpha shape \) -composite   red_outlined.gif
alternately if you kite just a soft semi-transparent 'halo' effect (for PNG)

Code: Select all

convert  http://www.imagemagick.org/Usage/images/knight.png \
       \(  +clone +level-colors red  -channel RGBA -blur 0x1 \
           -channel A -level 0,50% +channel \) \
       -compose DstOver -composite  red_halo.png
Just change red to whatever color you want!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Adding Layer Stroke Around Perimiter of Art

Post by anthony »

anthony wrote:I would do the same, but use 'EdgeOut' to get an edge OUTSIDE the shape ;-)

Code: Select all

convert  http://www.imagemagick.org/Usage/images/knight.png \
        \(  +clone -alpha extract -morphology EdgeOut Diamond \
            -background red -alpha shape \) -composite   red_outlined.gif
Simplification. Morphology can be applied directly to Alpha Channel!
You don't need to extract and re-add it :-)

Code: Select all

convert  http://www.imagemagick.org/Usage/images/knight.png \ 
             \(  +clone -channel A -morphology EdgeOut Diamond \
                 +channel +level-colors red \) -composite  red_outlined.gif
This has been placed in IM examples at
Masking, Outline or Halo transparency
http://www.imagemagick.org/Usage/masking/#outline
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Re: Adding Layer Stroke Around Perimiter of Art

Post by dfelder »

Is there a way to do this in individual lines instead of the composite you've indicated? I use VBA (MSAccess) and Windows Command Line (c:\ prompt), and I cannot figure out how to code these types of multi-line commands...

Convert:

convert http://www.imagemagick.org/Usage/images/knight.png \
\( +clone -channel A -morphology EdgeOut Diamond \
+channel +level-colors red \) -composite red_outlined.gif


To something in this type of format:

objMi.Convert "-background", "none", "-layers", "merge", "-trim", myimagename1, myimagename
objMi.Convert "-thumbnail", "100x100", myimagename, myimagename
objMi.Composite "-compose", "Dst_Over", "-tile", "pattern:checkerboard", myimagename, myimagename
objMi.Convert myimagename, "-strip", myimagename


THIS CODE BELOW DOESN'T WORK (it only generates the stroke layer):

objMi.Convert myimagename1, "\(", "+clone", "\", "-channel", "C", "-morphology", "EdgeOut", "Diamond", "+channel", "\", "+level-colors", "red", "\", "\)", "-composite", myimagename2


Can I rather just use multiple individual commands to get the same result? If so, how does this break down?
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Re: Adding Layer Stroke Around Perimiter of Art

Post by dfelder »

Looking back at a post that I missed over the weekend, I saw where this would work:

C:\>convert offset.png ( -clone 0 -alpha off ) ( -clone 0 -alpha extract ) ( +clone -edge 1 ) ( -clone 1 -clone 3 -clone 3 -compose over -composite ) -delete 0,1,3 +swap -compose copy_opacity -composite offset1.png

I ran it, and it ALMOST works. I get a very small outline around the perimeter. Is there a way to use something like this to make the outline 4 black pixels?

My struggle is that coding with VB is relatively complicated (versus command line), and when I try using the various solutions they never seem to completely work. Either I get a tiny & nearly invisible stroke, or I get a stroke layer that isn't composited with the original layer.

I also tried the example that was just added to the site:

convert knight.png \( +clone \
-channel A -morphology EdgeOut Diamond +channel \
+level-colors red \
\) -compose DstOver -composite knight_outlined.png

But that didn't seem to do the trick, either.
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Re: Adding Layer Stroke Around Perimiter of Art (SOLVED sort

Post by dfelder »

So I finally figured it out...

My ultimate task was to take an image with transparency, trim it, add a stroke, add a checkerboard background, thumbnail it, and remove the color profile...then convert it to work with the VB module. For those unfamiliar with the VB integration, or those needing to perform a similar task, here you go...

BTW, can anyone point out a more efficient way to make this happen?

Code: Select all

               Set objMi = New ImageMagickObject.MagickImage
                          objMi.Convert "-background", "none", "-layers", "merge", "-trim", myimagename1, myimagename
                          objMi.Convert "-thumbnail", "150x150", myimagename, myimagename
                          objMi.Convert myimagename, "(", "+clone", "-channel", "A", "-morphology", "Edge", "square:4", "+channel", "+level-colors", "black", ")", "-compose", "DstOver", "-composite", myimagename
                          objMi.Composite "-compose", "Dst_Over", "-tile", "pattern:checkerboard", myimagename, myimagename
                          objMi.Convert myimagename, "-strip", myimagename

               Set objMi = Nothing
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Adding Layer Stroke Around Perimiter of Art

Post by anthony »

dfelder wrote:THIS CODE BELOW DOESN'T WORK (it only generates the stroke layer):

objMi.Convert myimagename1, "\(", "+clone", "\", "-channel", "C", "-morphology", "EdgeOut", "Diamond", "+channel", "\", "+level-colors", "red", "\", "\)", "-composite", myimagename2
What is a 'C' layer??? That should be 'A'

To make the outline thicker, use a bigger kernel. such as Disk:5.3
See http://www.imagemagick.org/Usage/morphology/#disk

If you trim the image you will have to expand it slightly again (using -border)
otherwise you have no space to hold your outline!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply