Transparent bg + drop shadow + trim does not trim out transparent pixels

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
elmimmo
Posts: 26
Joined: 2011-02-02T05:42:42-07:00
Authentication code: 8675308

Transparent bg + drop shadow + trim does not trim out transparent pixels

Post by elmimmo »

The color that -trim cuts out seems to be of a higher color depth than the output's, and therefore leaves in colors that in the output will be the same as the corner pixels onced rounded down to the output's color depth. How do I reduce the bit depth of ImageMagick's buffer so that -trim works based on the bit depth of the output? -depth seems to alter only the bit depth of the output, but not ImageMagick's internal buffer.

I am trying to apply a drop shadow to non-square images on a transparent canvas (say, a solid circle on a transparent canvas), and then trimming out all transparent pixels before outputting. But -trim leaves in some pixels around the drop shadow that in the output are 100% transparent, seemingly due to them not being completely so while still inside ImageMagick. I know I could use -fuzz to get approximate results, but I need -trim to be 100% accurate, not fuzzy.

Code: Select all

convert "input.png" \
        \( "input.png" -alpha extract \) \
        -matte -bordercolor none -border 100x100 \
        -alpha off -compose copy_opacity -composite -compose over \
        \( -clone 0 -background black -shadow 25x4+3+4 \) \
        +swap \
        -background none -layers merge \
        -trim \
        "output.png"
That command does this:
  1. expands the canvas to give the drop shadow a bit of room
  2. creates a drop shadow from the alpha
  3. places the drop shadow under the original image
  4. and finally trims out transparent pixels.
That, though leaves a margin of six 100% transparent pixels or so around the image.

Getting pixel enumeration, by appending txt: >out.txt to the command above, reveals the disparity between ImageMagick's image buffer and the output:

Code: Select all

# ImageMagick pixel enumeration: 522,322,65535,srgba
0,0: (0,0,0,0)  #00000000  none
[…]
487,0: (0,0,0,1)  #00000000  srgba(0,0,0,1.5259e-05)
So ImageMagick's image buffer is 16 bit per channel, whereas I am exporting to 8 bit per channel. The pixel 487,0 is not 100% transparent in 16 bit but it becomes so in 8 bit. How do I get -trim to look at the image in 8 bit.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Transparent bg + drop shadow + trim does not trim out transparent pixels

Post by snibgo »

What version IM are you using? What Q-number, with or without HDRI?
elmimmo wrote:-depth seems to alter only the bit depth of the output, but not ImageMagick's internal buffer.
Correct. The internal buffer has the depth defined at compile-time: Q8, 16, 32 or 64.
elmimmo wrote:How do I reduce the bit depth of ImageMagick's buffer so that -trim works based on the bit depth of the output?
You can use eg Q8 instead of Q16. For a similar effect, use "-colors 256" on the extracted alpha channel.
snibgo's IM pages: im.snibgo.com
elmimmo
Posts: 26
Joined: 2011-02-02T05:42:42-07:00
Authentication code: 8675308

Re: Transparent bg + drop shadow + trim does not trim out transparent pixels

Post by elmimmo »

snibgo wrote:What version IM are you using? What Q-number, with or without HDRI?

Code: Select all

$ convert --version
Version: ImageMagick 6.9.5-5 Q16 x86_64 2016-08-07 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2016 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC Modules 
Delegates (built-in): bzlib freetype jng jpeg ltdl lzma png tiff xml zlib
snibgo wrote:The internal buffer has the depth defined at compile-time: Q8, 16, 32 or 64.

You can use eg Q8 instead of Q16. For a similar effect, use "-colors 256" on the extracted alpha channel.
My question was more about how to downgrade the bit-depth of the image stored in the buffer (rather than the buffer itself) at some point within the command chain (specifically once the drop shadow has been drawn and placed below the original image, no before) so that -trim works predictably as one would assume by looking at the untrimmed output.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Transparent bg + drop shadow + trim does not trim out transparent pixels

Post by snibgo »

elmimmo wrote:So ImageMagick's image buffer is 16 bit per channel, whereas I am exporting to 8 bit per channel.
Your command doesn't explicitly define the output as 8 bits/channel. I suppose your input is 8 b/c, so IM reduces the output. Personally, I would work in the opposite direction, using "+depth" before the output, so it isn't reduced.

But you are trimming based on the alpha channel, and you want that to be 8 bits. As I said, the obvious way to do that is to extract the alpha, "-colors 256", and CopyOpacity it back to the image.

IM doesn't have a simple command to reduce the depth of pixels, to "knock out" trailing bits. But the way to do this is to divide, then multiply. If we divide by 256 then multiply by 256, this will zero the bottom 8 bits. We don't normally want exactly that. Instead, we want bit reduction and bit replication, so we use 257 instead of 256.
snibgo's IM pages: im.snibgo.com
elmimmo
Posts: 26
Joined: 2011-02-02T05:42:42-07:00
Authentication code: 8675308

Re: Transparent bg + drop shadow + trim does not trim out transparent pixels

Post by elmimmo »

snibgo wrote:the obvious way to do that is to extract the alpha, "-colors 256", and CopyOpacity it back to the image.
Could you please rewrite my command above to include your suggested modification? I tried, but am not too sure would it should go (the alpha must be reduced to 8 bit after the generation of the drop shadow) nor whether I need to add additional commands. I did not get it to behave differently than how it is working now.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Transparent bg + drop shadow + trim does not trim out transparent pixels

Post by snibgo »

You haven't supplied input.png so I can't test this:

Code: Select all

convert "input.png" \
\( "input.png" -alpha extract \) \
-matte -bordercolor none -border 100x100 \
-alpha off -compose copy_opacity -composite -compose over \
\( -clone 0 -background black -shadow 25x4+3+4 \) \
+swap \
-background none -layers merge \
\( -alpha extract -colors 256 -alpha off -compose copy_opacity -composite -compose over \) \
-trim \
"output.png"
If that doesn't work, please supply a link to input.png.
snibgo's IM pages: im.snibgo.com
elmimmo
Posts: 26
Joined: 2011-02-02T05:42:42-07:00
Authentication code: 8675308

Re: Transparent bg + drop shadow + trim does not trim out transparent pixels

Post by elmimmo »

snibgo wrote:

Code: Select all

convert "input.png" \
\( "input.png" -alpha extract \) \
-matte -bordercolor none -border 100x100 \
-alpha off -compose copy_opacity -composite -compose over \
\( -clone 0 -background black -shadow 25x4+3+4 \) \
+swap \
-background none -layers merge \
\( -alpha extract -colors 256 -alpha off -compose copy_opacity -composite -compose over \) \
-trim \
"output.png"
If that doesn't work, please supply a link to input.png.
It does not work:

Code: Select all

convert: no images defined `output.png' @ error/convert.c/ConvertImageCommand/3257.
Here you have a sample input.png.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Transparent bg + drop shadow + trim does not trim out transparent pixels

Post by snibgo »

Oops, sorry, I forgot to "clone", and put the end-parens in the wrong place. Try:

Code: Select all

convert "input.png" \
\( "input.png" -alpha extract \) \
-matte -bordercolor none -border 100x100 \
-alpha off -compose copy_opacity -composite -compose over \
\( -clone 0 -background black -shadow 25x4+3+4 \) \
+swap \
-background none -layers merge \
\( +clone -alpha extract -colors 256 \) -alpha off -compose copy_opacity -composite -compose over \
-trim \
"output.png"
Your link doesn't work for me (I get a blank page).
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Transparent bg + drop shadow + trim does not trim out transparent pixels

Post by fmw42 »

The link works for me. I get a black ellipse on transparent background. But the base image is black and the alpha channel has all the detail.
elmimmo
Posts: 26
Joined: 2011-02-02T05:42:42-07:00
Authentication code: 8675308

Re: Transparent bg + drop shadow + trim does not trim out transparent pixels

Post by elmimmo »

Works. Thanks!
Post Reply