How to create drop shadow on resized image with an extension?

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?".
TomXampp
Posts: 26
Joined: 2015-12-02T00:21:23-07:00
Authentication code: 1151

How to create drop shadow on resized image with an extension?

Post by TomXampp »

I'm making JPG thumbnails of images of varying sizes. I'm resizing them while preserving aspect ratio so that neither H nor W is greater than 88px, and the resulting image is centered on a 100x100px #eeeeee "canvas" created with -extent:

Code: Select all

convert source.jpg -resize 88x88 -background #eeeeee -gravity center -extent 100x100 destination.jpg
This works perfectly. However, I want the image (at the center of the #eeeeee canvas) to have a drop shadow. I understand this typically involves superimposing several layers, but I can't find the correct sequence of switches to do this, and preferably I'd want to do it as a one-liner (i.e., one long command).

How can this be done?
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: How to create drop shadow on resized image with an extension?

Post by snibgo »

On drop shadows, see http://www.imagemagick.org/Usage/blur/#shadow

I think you want to create a drop shadow (which is semi-transparent), then flatten the output against an opaque colour. Finally, "-extent". Windows BAT syntax:

Code: Select all

%IMG7%magick ^
  rose: ^
  ( +clone -background navy -shadow 80x3+5+5 ) ^
  +swap ^
  -background none -layers merge +repage ^
  -background #eee ^
  -layers flatten ^
  -gravity Center -extent 100x100 ^
  shadow.png
snibgo's IM pages: im.snibgo.com
TomXampp
Posts: 26
Joined: 2015-12-02T00:21:23-07:00
Authentication code: 1151

Re: How to create drop shadow on resized image with an extension?

Post by TomXampp »

Hmm. Something's not working. Let's confirm version compatibility first. I'm using:
ImageMagick 7.0.8-47 Q8 x64 2019-05-27
When I run the first example at the "Generating Shadows" tutorial you hyperlinked (http://www.imagemagick.org/Usage/blur/#shadow):

Code: Select all

convert rose: ( +clone  -background navy  -shadow 80x3+5+5 ) +swap -background none   -layers merge  +repage   shadow.png
...I get:

Image

...not the example image provided in the tutorial, which is:

Image

Reproducing this seems to be the first step in finding the solution to my task. What's going wrong?
TomXampp
Posts: 26
Joined: 2015-12-02T00:21:23-07:00
Authentication code: 1151

Re: How to create drop shadow on resized image with an extension?

Post by TomXampp »

Wait, I read some other posts related to this issue, and there appears to be a bug affecting this in the version of IM I was using. So I've installed the current version:
Version: ImageMagick 7.0.8-66 Q16 x64 2019-09-22
...and the rose conversion above completes successfully.

I'm very close to solving the problem, but one thing remains. My command is:

Code: Select all

convert rose: -resize 88x88 ( +clone -background #000 -shadow 63x3+5+5 ) +swap -background none -layers merge +repage -background #c2c5cc -layers flatten -gravity center -extent 100x100 output.jpg
...but the rose image is not centered horizontally nor vertically. See:

Image

(My ultimate background color is #eee, but I've used #c2c5cc so that it can be seen easily against the light blue of this forum post.)

It would appear that

Code: Select all

-gravity center
isn't centering the image. Note that I'm resizing the source image so its longest side is no greater than 88, and the resulting image is 100x100. What needs to be done additionally for the centering to work?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to create drop shadow on resized image with an extension?

Post by fmw42 »

It is centered when you consider how far the shadow extends down and to the right. It is further than you can see as it fades away. You can see that by the following where I have listed out the size before you extent it and put a green border around it before you extent it.

Code: Select all

convert rose: -resize 88x88 ^
( +clone -background black -shadow 63x3+5+5 ) ^
+swap -background none -layers merge +repage ^
-background "#c2c5cc" -layers flatten -format "%wx%h" +write info: ^
-shave 1x1 -bordercolor green1 -border 1 ^
-gravity center -extent 100x100 output.jpg
TomXampp
Posts: 26
Joined: 2015-12-02T00:21:23-07:00
Authentication code: 1151

Re: How to create drop shadow on resized image with an extension?

Post by TomXampp »

Okay, I see what you mean. But that doesn't solve my problem. How do I make the image centered, like this, with the drop shadow falling off the centered image:

Image

?
TomXampp
Posts: 26
Joined: 2015-12-02T00:21:23-07:00
Authentication code: 1151

Re: How to create drop shadow on resized image with an extension?

Post by TomXampp »

Aha! I figured it out. If I make a second clone and put an INVISIBLE shadow on it shifted to the opposite corner of the image, I'll have an image that, when centered, creates the exact effect I'm seeking:

Code: Select all

convert rose: -resize 88x88 ( +clone -background #000 -shadow 63x3+2+2 ) +swap ( +clone -background #000 -shadow 0x3-2-2 ) +swap -background none -layers merge +repage -background #c2c5cc -layers flatten -gravity center -extent 100x100 output.jpg
And here is the final product:

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

Re: How to create drop shadow on resized image with an extension?

Post by fmw42 »

Composite your shadowed image with top left offset by computing the different in sizes between your resized rose image size and the background size of 100x100, ignoring the shadow.


new width = 88
new height by proportion = 88*46/70 = 57.8
xoffset = (100-88)/2 = 6
yoffset = (100-58)/2 = 21

Code: Select all

convert rose: -resize 88x88 ^
( +clone -background black -shadow 63x3+5+5 ) ^
+swap -background none -layers merge +repage ^
-background "#c2c5cc" -layers flatten +repage ^
( -size 100x100 xc:"#c2c5cc" ) ^
+swap -geometry +6+21 -compose over -composite ^
result.png
TomXampp
Posts: 26
Joined: 2015-12-02T00:21:23-07:00
Authentication code: 1151

Re: How to create drop shadow on resized image with an extension?

Post by TomXampp »

Nice, but it's not perfectly centered. The top margin is greater than the bottom margin (not immediately visible but measurable), and the left margin is visibly greater than the right margin (set the shadow to 0x3+5+5 and you'll see the difference).
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to create drop shadow on resized image with an extension?

Post by fmw42 »

Off by how much. Did you check by computations for any errors? It should only be off by a fraction of a pixel unless I made an error in my computations of the new height and/or yoffset.
TomXampp
Posts: 26
Joined: 2015-12-02T00:21:23-07:00
Authentication code: 1151

Re: How to create drop shadow on resized image with an extension?

Post by TomXampp »

It can be verified by opening the resulting image in Photoshop, switching the ruler to pixels, zooming in, and measuring:

The left margin is 7px, the right margin is 5px.
The top margin is 22px, the bottom margin is 20px.

Image

It may be easier to see if the shadow's opacity is set to 0% in the command, not 63%:

Image

You may need to download them to see them, but I can see the discrepancy between the left and right margins in the 0-opacity version just viewing it here.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to create drop shadow on resized image with an extension?

Post by fmw42 »

My mistake. Replace 6 with 5 and 21 with 20, since indexing starts at 0 not 1. (5 is the sixth pixel from 0, 20 is the twenty first pixel from 0)
TomXampp
Posts: 26
Joined: 2015-12-02T00:21:23-07:00
Authentication code: 1151

Re: How to create drop shadow on resized image with an extension?

Post by TomXampp »

That does work perfectly for the rose example, but it's not useful for images of other sizes. I'm using this routine to make thumbnails from images of arbitrary sizes. This routine only seems to work for the rose image.

The method I outlined earlier, making two clones with a visible (63 opacity) shadow for one but an invisible (0 opacity) shadow diagonally across from it, works for all image sizes, with the single problem that the shadow does not fill out completely at the southeast corner of the image (there's a "chip" in the shadow in the resulting image).

However, the routine that we're exploring here shifts the 88x88 image to different locations within the 100x100 background in ways I cannot predict. (The first image I tried it with, which was wider than taller, shifted the 88x88 to the bottom of the 100x100 background; another image, which was taller than wider, resulting in the 88x88 image being on the left side of the 100x100 background image.) Try running arbitrary images on your machine with--replacing "rose:" with the image name--and see the different results you get in the placement of the 88x88 image. I'm interested in getting this method to work, as there isn't a "chip" in the shadow at the southeast corner.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to create drop shadow on resized image with an extension?

Post by fmw42 »

My method should work for any image. You just have to compute the offsets as I did with one exception. You have to test whether the input image is portrait (taller than wide) or landscape (wider than tall), because the larger dimension will end up 88 and the smaller dimension will have to be computed in proportion. The example above works because the rose: image is landscape and so the width will be 88 and the height must be computed. If the image is portrait mode then the height will be 88 and the width will have to be computed. This can all be done in-line if you use ImageMagick 7. But for ImageMagick 6, you have to precompute those offsets. That is OS dependent. I can do it for Unix, but I do not use or know Windows scripting for variables.
TomXampp
Posts: 26
Joined: 2015-12-02T00:21:23-07:00
Authentication code: 1151

Re: How to create drop shadow on resized image with an extension?

Post by TomXampp »

Have you tried your method on images to check? It doesn't work as you describe, or perhaps I don't understand.

If I understand your explanation, the routine as it stands will work for landscape images. Here is a 4:5 landscape image:

Image

After processing it with the routine, it appears this way as a thumbnail:

Image

It's not centered, and that's not good. But if you mean I'd need to adjust the formula for *every* image to be processed by it, then it's not very useful. The routine I crafted earlier works without any adjustment whatsoever...any image I use is automatically positioned correctly, with space for the shadow accommodated without losing perfect centering.

How can the routine in question be improved so that all variables are accounted for without having to tweak the formula each time?
Post Reply