Outline image on transparent background

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
alex

Outline image on transparent background

Post by alex » 2010-06-10T12:46:54-07:00

Trying to add outline to image on the transparent background (want to get something similar to photoshop stroke),
tried to use -shadow but if set sigma to 0 the shadow is not visible while with sigma>0 it's blured what's not what I need neither.

What's the good way to make color outline (stoke)? Please help.

snibgo
Posts: 11999
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Outline image on transparent background

Post by snibgo » 2010-06-10T13:01:52-07:00

I wouldn't know a Photoshop stroke if it hit me in the face.

If you provide a before and after sample, someome might make a suggestion.
snibgo's IM pages: im.snibgo.com

alex

Re: Outline image on transparent background

Post by alex » 2010-06-10T13:11:48-07:00

snibgo wrote:I wouldn't know a Photoshop stroke if it hit me in the face.

If you provide a before and after sample, someome might make a suggestion.
sure...here's how it looks like in photoshop:

Image

the 'before' was just without the red outline

snibgo
Posts: 11999
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Outline image on transparent background

Post by snibgo » 2010-06-10T14:28:59-07:00

There are many ways of doing this. Here is one (Windows script):

Make a source file:

Code: Select all

convert logo: -fuzz 15%% -transparent White strokedIn.png
Create a red "stroke" around the opaque parts, 20 pixels wide:

Code: Select all

convert ^
  strokedIn.png ^
  ( ^
    +clone ^
    -fill White -colorize 100%% ^
    -background Black -flatten ^
    -morphology Dilate Disk:20 ^
    -blur 0x1 ^
    -alpha Copy ^
    -fill Red -colorize 100%% ^
  ) ^
  +swap ^
  -composite ^
  strokedOut.png
Image
snibgo's IM pages: im.snibgo.com

User avatar
fmw42
Posts: 25388
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Outline image on transparent background

Post by fmw42 » 2010-06-10T15:32:14-07:00

Make a binary mask, then blur and threshold and colorize, then overlay the image using the original mask on the colored background.

original:
Image

floodfill the outside area with red; change non-red to black, change red to white, clean up small dots using morphology close:
convert cow_bw.gif -fill red -fuzz 5% -draw "color 0,0 floodfill" -fill black +opaque red -fill white -opaque red -alpha off -morphology close diamond cow_bw_mask.gif

Image

For 5 pixel stroke:
convert cow_bw_mask.gif -negate -blur 5x65000 -threshold 0 -negate -fill red -opaque black cow_bw_mask2.gif

Image

composite together:
convert cow_bw_mask2.gif cow_bw.gif \( cow_bw_mask.gif -negate \) -compose over -composite cow_bw_redborder.gif
Image

Note: commands would have been a bit simpler if I had negated the original mask. Most of the other negates would not be needed and the -morphology close would become -morphology open
Last edited by fmw42 on 2010-06-11T14:03:06-07:00, edited 1 time in total.

alex

Re: Outline image on transparent background

Post by alex » 2010-06-11T08:13:21-07:00

snibgo wrote:There are many ways of doing this. Here is one (Windows script):

Make a source file:

Code: Select all

convert logo: -fuzz 15%% -transparent White strokedIn.png
Create a red "stroke" around the opaque parts, 20 pixels wide:

Code: Select all

convert ^
  strokedIn.png ^
  ( ^
    +clone ^
    -fill White -colorize 100%% ^
    -background Black -flatten ^
    -morphology Dilate Disk:20 ^
    -blur 0x1 ^
    -alpha Copy ^
    -fill Red -colorize 100%% ^
  ) ^
  +swap ^
  -composite ^
  strokedOut.png
Image
Thank you for the response!

It works pretty well except some things -
I need a sharp edge of the stroke so I removed the -blur from the command but the result is
bad on the sharp corners

Image
See how it looks on the needles.

Second major issue - I have to apply it to the pretty large image (about 2500 pixels wide and high),
and it takes minutes to produce the result while photoshop takes few seconds to add the stroke.
The images are here:
http://www.ansata.biz/alex/file500.png - the small file and
http://www.ansata.biz/alex/lfile.png - the large file

May be there some other ways to add the stroke which will work faster and produce better result?

alex

Re: Outline image on transparent background

Post by alex » 2010-06-11T08:16:21-07:00

fmw42 wrote:Make a binary mask, then blur and threshold and colorize, then overlay the image using the original mask on the colored background.

original:

floodfill the outside area with red; change non-red to black, change red to white, clean up small dots using morphology close:
convert cow_bw.gif -fill red -fuzz 5% -draw "color 0,0 floodfill" -fill black +opaque red -fill white -opaque red -alpha off -morphology close diamond cow_bw_mask.gif

For 5 pixel stroke:
convert cow_bw_mask.gif -negate -blur 5x65000 -threshold 0 -negate -fill red -opaque black cow_bw_mask2.gif

composite together:
convert cow_bw_mask2.gif cow_bw.gif \( cow_bw_mask.gif -negate \) -compose over -composite cow_bw_redborder.gif

Note: commands would have been a bit simpler if I had negated the original mask. Most of the other negates would not be needed and the -morphology close would become -morphology open
Thank you for the method, but I wasn't able to reproduce it on my image - it have alpha channel and seems the blur result is just not visible under the mask.
Could you please write me the code to use with image with alpha channel?

snibgo
Posts: 11999
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Outline image on transparent background

Post by snibgo » 2010-06-11T10:04:34-07:00

For my method, we can fix the problem around the spikes with a suitable threshold:

Code: Select all

convert ^
  lfile.png ^
  ( ^
    +clone ^
    -fill White -colorize 100%% ^
    -background Black -flatten ^
    -morphology Dilate Disk:20 ^
    -threshold 50%% ^
    -alpha Copy ^
    -fill Red -colorize 100%% ^
  ) ^
  +swap ^
  -composite ^
  strokedOut.png
It takes 47 seconds on my laptop, which may be far too long.

Fmw's method takes 11 seconds:

Code: Select all

convert ^
  lfile.png ^
  -bordercolor none -border 20 ^
  lfilebord.png

convert ^
  lfilebord.png ^
  -evaluate set 0 ^
  -background White -flatten ^
  -negate ^
  bw_mask.gif

convert ^
  bw_mask.gif ^
  -blur 20x6 -threshold 0 ^
  -fill red -opaque White ^
  -transparent Black ^
  bw_mask2.png

convert ^
  bw_mask2.png ^
  lfilebord.png ^
  bw_mask.gif ^
  -compose over -composite ^
  redborder.png
The four commands could be combined into one, which would speed it up a little.

I have added a convert at the start to increase the size of the image, so the red border doesn't get clipped. I have changed the blur to "20x6", which improves the effect at the spikes.

This shows your original has transparency where you probably don't want it.
snibgo's IM pages: im.snibgo.com

User avatar
fmw42
Posts: 25388
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Outline image on transparent background

Post by fmw42 » 2010-06-11T11:03:51-07:00

Thank you for the method, but I wasn't able to reproduce it on my image - it have alpha channel and seems the blur result is just not visible under the mask.
Could you please write me the code to use with image with alpha channel?
alex



Please post a link to your original image.

alex

Re: Outline image on transparent background

Post by alex » 2010-06-11T12:27:46-07:00

fmw42 wrote:
Thank you for the method, but I wasn't able to reproduce it on my image - it have alpha channel and seems the blur result is just not visible under the mask.
Could you please write me the code to use with image with alpha channel?
alex



Please post a link to your original image.
Here are the small and the large files:

http://www.ansata.biz/alex/file500.png - the small file and
http://www.ansata.biz/alex/lfile.png - the large file

User avatar
fmw42
Posts: 25388
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Outline image on transparent background

Post by fmw42 » 2010-06-11T14:17:18-07:00

input:

Image

convert file500.png \ <--- input image
\( -clone 0 -alpha extract -threshold 0 \) \ <--- extract alpha channel and threshold as it was not binary
\( -clone 1 -blur 10x65000 -threshold 0 \) \ <--- blur and re-threshold the extacted alpha channel from previous line
\( -clone 2 -fill red -opaque white \) \ <--- take previous result and convert white to red
\( -clone 3 -clone 0 -clone 1 -alpha off -compose over -composite \) \ <--- composite red image with original using blurred image
-delete 0,1,3 +swap -alpha off -compose copy_opacity -composite \ <--- delete unneeded temps, put blurred image as alpha
file500_redborder.png <--- result

Image

alex

Re: Outline image on transparent background

Post by alex » 2010-06-14T10:31:47-07:00

Thank you very much, I think everything's good enough for me now!

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

Re: Outline image on transparent background

Post by anthony » 2010-06-15T00:49:22-07:00

how about a little trickiness to make it faster..

Red- Halo...
convert file500.png -bordercolor none -border 20x20 \
-background Red -alpha background \
-channel A -blur 0x20 -level 0,50% red_halo.png
Image

I'll leave it as an exercise to figure out.

Of course this is NOT a proper 'reversed' feather which is what you are after. The 'barbed wire' on the right is also faded!

So we get back to what was being done. however my version as with most of the others I have seen also has one serious problem. It does not preserve the anti-alising of the original image!!!!

To do that you MUST generate the red halo separately, and then overlay the original image onto it so it can anti-alias with that image. making the red-halo edge itself anti-alsied is even more of a problem, and the simplist solution is to blur or feather its edge slightly.

I suggest you have a look at my raw notes on true feathering, and try to 'invert it.
http://www.imagemagick.org/Usage/morpho ... ce_feather

Lets see if we can do better!!!!!

However while it will let you generate a nice and proper halo effect, it will not help generate a proper 'anti-aliased' edge on a sharp halo.

ASIDE: I am planning on creating a -feather operator that will directly make use of the technique found in the above.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/

Post Reply