Page 1 of 2

-shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-14T09:00:30-07:00
by artshevtsov
I'm trying to create a Photoshop inner-shadow effect, same as css3 box-shadow inset effect.

Step 1 (i'm generating button - rounded rectangle):

Code: Select all

convert -size 220x50 xc:none -fill '#bdbdbd' -draw 'roundrectangle 0,0 219,49 25,25' /var/www/test.local/public/images/button.png
I got an image - it's ok:

Image

Step 2 (have fail here - i'd like to get a result you can see on image below, i've made it with Photoshop):

Image - sorry for background - it should be transparent, not white

How to apply this effect to my rounded rectangle, using imagemagick -shadow and maybe some options like repage or compose?

All that I have achieved is similar effect, but shadow color equals to rectangle background color - i cant find way to adjust background color and shadow color separately :(

Code: Select all

convert -size 220x50 xc:none -fill '#d936d9' -draw 'roundrectangle 0,0 219,49 25,25' /var/www/test.local/public/images/button_tmp_2.png
convert /var/www/test.local/public/images/button_tmp_2.png \( +clone -fill '#d936d9' -shadow 80x5+0+0 -channel A -level 0,50% +channel \) -background none -compose src-over -flatten
Image - background color and shadow color are the same (-fill '#d936d9')


P.S.: i can't find any example here http://www.imagemagick.org/Usage/thumbnails/#shadow that works for my case.

Also i have a problem with rounded border when rounded corders radius >=4, some strange artefact appears in the right bottom corder :(

Code: Select all

convert /var/www/test.local/public/images/button.png -format 'roundrectangle 4,4 223,53 5,5' \ -write info:/var/www/test.local/public/images/tmp.mvg \ -alpha set -bordercolor none -border 4 \ \( +clone -alpha transparent -background none \ -fill white -stroke none -strokewidth 4 -draw @/var/www/test.local/public/images/tmp.mvg \) \ -compose DstIn -composite \ \( +clone -alpha transparent -background none \ -fill none -stroke '#dcbfde' -strokewidth 4 -draw @/var/www/test.local/public/images/tmp.mvg \) \ -compose Over -composite 
result images:

Image - radius 4

but radius 3 is ok:

Code: Select all

convert /var/www/test.local/public/images/button.png -format 'roundrectangle 3,3 222,52 5,5' \ -write info:/var/www/test.local/public/images/tmp.mvg \ -alpha set -bordercolor none -border 3 \ \( +clone -alpha transparent -background none \ -fill white -stroke none -strokewidth 3 -draw @/var/www/test.local/public/images/tmp.mvg \) \ -compose DstIn -composite \ \( +clone -alpha transparent -background none \ -fill none -stroke '#520a52' -strokewidth 3 -draw @/var/www/test.local/public/images/tmp.mvg \) \ -compose Over -composite 
Image - radius 3

Code: Select all

/var/www/test.local/public/images $ convert --version
Version: ImageMagick 6.6.0-4 2012-08-17 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2010 ImageMagick Studio LLC
Features: OpenMP

Re: -shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-14T10:38:31-07:00
by fmw42
Your IM version is rather old and may be the cause of the artifact. You should consider upgrading.

Re: -shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-14T12:11:40-07:00
by artshevtsov
fmw42 wrote:Your IM version is rather old and may be the cause of the artifact. You should consider upgrading.
Thanks for your reply, I'll try to upgrade.

And what about inner-shadow? I still can't make it work fine. Can somebody help with that?

Re: -shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-14T12:55:39-07:00
by fmw42
Best I can suggest for the time being as I am too busy right now to test, is to see Anthony's examples for creating buttons at http://www.imagemagick.org/Usage/thumbnails/#bubble and other sections on the same page

Re: -shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-14T17:20:57-07:00
by fmw42
Note the shadow color is controlled by -background (not -fill)

Re: -shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-14T17:29:02-07:00
by fmw42
I cannot reproduce your results with the code provided using IM 6.8.5.6 Q16 Mac OSX Snow Leopard


Neither this:

convert -size 220x50 xc:none -fill "#d936d9" -draw "roundrectangle 0,0 219,49 25,25" 1tmp1.png
convert 1tmp1.png \( +clone -fill '#d936d9' -shadow 80x5+0+0 -channel A -level 0,50% +channel +write 1tmp2.png \) \
-background none -compose src-over -flatten 1tmp3.png

nor this more compact version make the pink oval that you have shown

convert \( -size 220x50 xc:none -fill "#d936d9" -draw "roundrectangle 0,0 219,49 25,25" +write 1tmp1.png \) \
\( +clone -fill '#d936d9' -shadow 80x5+0+0 -channel A -level 0,50% +channel +write 1tmp2.png \) \
-background none -compose src-over -flatten 1tmp3.png

Re: -shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-14T17:54:16-07:00
by fmw42
This will make your gray inner shadow like image:


convert \( -size 220x50 xc:none -fill '#bdbdbd' -draw 'roundrectangle 0,0 219,49 25,25' \) \
\( -clone 0 -alpha extract \) \
\( -clone 0 -bordercolor none -border 9 -channel rgba -blur 9x65000 -shave 9x9 \) \
-delete 0 +swap -alpha off -compose copy_opacity -composite 1shaded_gray_oval.png

Image


Here is one way to colorize it:


convert \( -size 220x50 xc:none -fill '#bdbdbd' -draw 'roundrectangle 0,0 219,49 25,25' \) \
\( -clone 0 -alpha extract \) \
\( -clone 0 -bordercolor none -border 9 -channel rgba -blur 9x65000 -shave 9x9 \) \
-delete 0 +swap -alpha off -compose copy_opacity -composite -auto-level -alpha off +level-colors deeppink,pink -alpha on 1shaded_pink_oval.png

Image


Here is another way:


convert \( -size 220x50 xc:none -fill '#bdbdbd' -draw 'roundrectangle 0,0 219,49 25,25' \) \
\( -clone 0 -alpha extract \) \
\( -clone 1 -virtual-pixel black -morphology erode octagon:4 \) \
\( -clone 0 -bordercolor none -border 9 -channel rgba -blur 9x65000 -shave 9x9 \) \
\( -clone 3 -alpha off -auto-level +level-colors black,magenta \) \
\( -clone 3 -alpha off -auto-level +level-colors black,skyblue \) \
\( -clone 4 -clone 5 -clone 2 -compose over -composite \) \
-delete 0,2,3,4,5 +swap -alpha off -compose copy_opacity -composite 1shaded_magenta_skyblue_oval.png

Image

Re: -shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-14T22:09:43-07:00
by anthony
The problem is generating a gradient of some kind around a shape.

Once you have a gradient you can color that gradient in many different ways. Using +level-colors, or Color Lookup Tables (-clut).
The gradient generated is typically linear (no roll off), but you can adjust that gradient using functions like sigmoidal contrast, or as part of the color lookup replacement.

To generate the gradient for the edge of a shaped image, regardless of if it is internal or external, there are quite a number of ways
  • Using a blur (non-linear)
  • Using blur with a radius and large sigma (square area averaging) -- a method favored by Fred and shown above
  • using a convolve with a shaped kernel (shaped area averaging)
See... Mean or Average Filtering using Shape Kernels
http://www.imagemagick.org/Usage/convolve/#mean

These are all basically the technique of blurred convolution, just using a differnet 'kernel' generated in different ways. For practical use they generally need to have some level adjustments and perhaps even masking with the original shape to restore that shape.

But there is another method of generating a gradient based on distance to nearest edge (note that this it can produce ridges, known as a skeleton of the shape). This is a pure linear gradient, and is known as morphology distance gradient.
http://www.imagemagick.org/Usage/morphology/#distance
and more specifically special handling for anti-aliased (non-boolean) shapes.
http://www.imagemagick.org/Usage/morpho ... anti-alias

For the shape you have the linear (square) bluring will probably be good enough (as showen in previous posts) but for highly variable shapes, larger ranges (which is veru slow in blur), or accuracy then the morphology gradient will likely be better.


Addendum... There is one other way of generating a shaped gradient... Sparse Color 'Shepard's Interpolation'.
See: Sparse Color as a Fill Operator
http://www.imagemagick.org/Usage/canvas/#sparse_fill

A similar method (Diffusion Gradients) is also possible, but not available in ImageMagick as yet.

Re: -shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-14T22:25:08-07:00
by fmw42
I used a linear (ramp) blur rather than gaussian so that I could add the exact border I needed to blur and then shave off afterwards. It also gave a better border ramp than a gaussian rolloff in this case.

Whether one uses a linear or gaussian roll-off depends upon the situation. Many time using a linear blur gives a rather squarish result that is not very pleasing. In that case a gaussian blur works better.

However, as a point of interest, I have tried numerous techniques to create vignetting effects and the best one by far is using the linear distance morphology rather than -blur. Also as Anthony points out, for more precise "feathering" effects of narrow features, the distance morphology works better than -blur.

Re: -shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-14T23:49:04-07:00
by anthony
fmw42 wrote:I used a linear (ramp) blur rather than gaussian so that I could add the exact border I needed to blur and then shave off afterwards. It also gave a better border ramp than a gaussian rolloff in this case.

Whether one uses a linear or gaussian roll-off depends upon the situation. Many time using a linear blur gives a rather squarish result that is not very pleasing. In that case a gaussian blur works better.

However, as a point of interest, I have tried numerous techniques to create vignetting effects and the best one by far is using the linear distance morphology rather than -blur. Also as Anthony points out, for more precise "feathering" effects of narrow features, the distance morphology works better than -blur.
Note it is only linear in any one direction. You have a different linear distance diagonally than orthogonally, as the use of a large sigma is essentially generating a 'square' area kernel. and this square averaging. But typically that is 'good enough'.

You get more distance proportional effect using a 'disk' kernel. I have not implemented named kernels for anti-aliased circles, which would produce a even more accurate for areas averaging. But as I mentioned generally a square is good enough, and the -blur with large sigma is equivalent to a convolve using a flat square shape.

Distance is calculating true distance from edge (where the edge is boolean, unless special anti-alias pixel handling is also applied before hand) rather than the 'weighted average over an area' you get with convolution.

However this is probably getting too high-level, for the OP. So unless the OP has something further, lets end this aspect here.

Re: -shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-15T04:53:49-07:00
by artshevtsov
fmw42 wrote:This will make your gray inner shadow like image:

convert \( -size 220x50 xc:none -fill '#bdbdbd' -draw 'roundrectangle 0,0 219,49 25,25' \) \
\( -clone 0 -alpha extract \) \
\( -clone 0 -bordercolor none -border 9 -channel rgba -blur 9x65000 -shave 9x9 \) \
-delete 0 +swap -alpha off -compose copy_opacity -composite 1shaded_gray_oval.png

Image
Oh, good examples, thank you for it, but i need to control angle of shadow, so it is not exactly what i need. I make some simple button generator using php+ imagemagick and my html form have 5 params to set shadow on the button:
color, opacity, angle, size, distance (like at photoshop)
then i process it with php on form submit.
So -shadow is good for that case, but i steel don't know how to implement it correctly.
i have php code like that to count params for -shadow option:

Code: Select all

...
$shadow_x = round($settings['shadow_distance'] * cos(deg2rad($settings['shadow_angle'])), 0);
	if($shadow_x>=0) {
		$shadow_x = '+'.$shadow_x;
	}
	$shadow_y = round($settings['shadow_distance'] * sin(deg2rad($settings['shadow_angle'])), 0);
	if($shadow_y>=0) {
		$shadow_y = '+'.$shadow_y;
	}
$cmd = "convert $filename ... -fill '{$settings['shadow_color']}' -shadow {$settings['shadow_opacity']}x{$settings['shadow_size']}{$shadow_x}{$shadow_y} ... "; // i want to apply shadow this way using  -shadow option but can't extract shadow and place it to the rounded rectangle created by previous convert command ( $filename is an already generated button, i left this code);
 exec($cmd);
...
If I use your command, angel always seems to be 90 degrees ;)
Is it possible to do with -shadow option?

Re: -shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-15T10:04:10-07:00
by fmw42
As far as I know, -shadow will only make a outside shadow and not inside.

I will have to experiment further, perhaps later today, but here is a test using -motion-blur

convert \( -size 220x50 xc:none -fill '#bdbdbd' -draw 'roundrectangle 0,0 219,49 25,25' \) \
\( -clone 0 -alpha extract \) \
\( -clone 0 -alpha off -background blue -virtual-pixel background -motion-blur 0x5+45 \) \
-delete 0 +swap -alpha off -compose copy_opacity -composite 1shaded_gray_oval2.png

Image



convert \( -size 220x50 xc:none -fill '#bdbdbd' -draw 'roundrectangle 0,0 219,49 25,25' \) \
\( -clone 0 -alpha extract \) \
\( -clone 0 -alpha off -background blue -virtual-pixel background -motion-blur 0x5-45 \) \
-delete 0 +swap -alpha off -compose copy_opacity -composite 1shaded_gray_oval3.png

Image

Can you provide a better example from Photoshop that is not evenly shaded like you want?

Re: -shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-15T17:28:40-07:00
by artshevtsov
fmw42 wrote: Can you provide a better example from Photoshop that is not evenly shaded like you want?
Of course ;) It's interesting!
Layer we work with, rounded rectangle again:
Image

I need to get 1 command that can provide me Inner Shadow effect with different values of parameters passed from html form (angle, distance, size, opacity)
For -shadow option i count x, y by distance and angle passed by user and also user passes params size=sigma, opacity=percent-opacity - it works fine for Drop Shadow and Text Shadow effects.

Example 1:
Image
Photoshop Inner Shadow effect settings (adjustments):
opacity: 75, distance 5, size: 5, angle 90
Image

Example 2:
Image
Photoshop Inner Shadow effect settings (adjustments):
opacity: 75, distance 2, size: 0, angle 90
Image

Example 3:
Image
Photoshop Inner Shadow effect settings (adjustments):
opacity: 75, distance 10, size: 0, angle 0
Image

Difference between Photoshop Inner Shadow and Drop Shadow (css3 box-shadow inset and box-shadow analogs):

Image

Conclusion:

Image

Modern buttons design combines border, inner-shadow, outer-shadow, gradient, text with color and shadow. My task is to simulate css3 effects using imagemagick to generate cross-browser buttons ;)
I have already done it, inner-shadow is the last problem i cant cope with ;)

Re: -shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-15T18:15:23-07:00
by fmw42
IM -shadow does not allow you to set the size and angle the same way that you have in PS.

IM -shadow opacityxsigma+x+y

opacity is the same.

sigma is typically about radius/3 but is only the rolloff of the shadow. That is how quickly it tapers off. Thus it will not produce an inner "blur" shadow. It only controls the blur of the outside shadow

you can compute x and y from x=distance*cos(angle) and y=distance*sin(angle)

So IM -shadow will be mostly like size=0 in PS.

Here are some examples.

Input: button.png
Image

Note: 5/3=1.7 or approx 2

Similar to your first example, but no inner shadow and tapered outer shadow:

convert button.png \( +clone -background black -shadow 75x1.7+0-5 \) +swap \
-background none -layers merge +repage button1.png

Image

Similar to your third example:

convert button.png \( +clone -background black -shadow 75x0+10+0 \) +swap \
-background none -layers merge +repage button2.png

Image


Similar to your first example, but with added -blur code to include inner shadow effect:

convert button.png \( +clone -background black -shadow 75x0+0-5 \) \
\( -clone 0 -alpha off -virtual-pixel black -blur 0x2 -alpha on \) \
-delete 0 -background none -layers merge +repage button3.png

Image


Same as previous example but using -motion-blur rather than -blur:

convert button.png \( +clone -background black -shadow 75x0+0-5 \) \
\( -clone 0 -alpha off -virtual-pixel black -motion-blur 0x3-90 -alpha on \) \
-delete 0 -background none -layers merge +repage button4.png

Image

Re: -shadow like photoshop inner-shadow on rounded rectangle

Posted: 2013-05-15T18:44:36-07:00
by anthony
Shadow only works on the image alpha shape. As such if you negate alpha, you can generate a shadow for the inside
of the image. That shadow will need to be masked by the original image (or overlayed using 'DstAtop' composition)

Shadow however generates a larger image, with an virtual canvas offset. Normal composition is too low level to use that offset (gravity effected geometry offset is used to pass the offset to composition), and without setting a offset the larger image displaces the shadow image. That is why you are getting miss-aligning of the images.

Actually shadow is simply a 'transparent colors blur',
See Shadow Internals
http://www.imagemagick.org/Usage/blur/#shadow_internals

You are better off DIY the internal edge blurs yourself, starting from the above 'internal' examples, not expanding the image, setting your own overlay offset (or geometry), rather than attempting to miss-use shadow.