Skip to main content

[JAVA2D] alphacomposite for combining drop shadows

1 reply [Last post]
Anonymous

For those that don't want to read my motivation for this email, here's
essentially what I'm looking for: Is there some sort of Composite that
does a comparison of the SRC and DEST pixels and retains the darker of
the two? If not, how would I go about implementing one? Or is there a
better way?

Here's why I'm asking: I'm trying to implement feathered drop shadows
for a number of rectangles and I'm having some difficulty combining the
resulting shadows into a smooth backdrop. For example, let's say I have
a rectangle A. The shadow that A casts is essentially a rounded
rectangle, but instead of using a RoundRectangle2D, I composed the
shadow out of a rectangle of the same size as A in the middle, 4 smaller
rectangles on the sides, top and bottom, and then 4 arcs for the 4
corners:

Arc Rect Arc
Rect Rect Rect
Arc Rect Arc

The rectangle in the middle is then painted black with an alpha value,
and then the 4 sides are painted the same black with a gradient paint
that is reduced heading outwards from the middle rectangle. The 4 arcs
on the corners are painted black with a RadialGradient paint the
lightens as you head outwards from the corner. So what I get for the
shadow is a nice rounded rectangle that is larger than the original with
a gradient paint on the edges that gradually lightens. This looks
great.

The problem arises when I have the rectangle A near or next to another
Rectangle, say B. If I use SRC_OVER as an alpha composite for the
shadow buffer, then the shadows (because they are larger than the
rectangles that cast them) combine as if they are from two light sources
and you get a dark section where they come together. If I use SRC, then
whichever shadow get's drawn second destroys the feathering around the
first shadow because the gradient paint on the edges of the second
shadow overwrites the edges on the first shadow.

So what I'm looking for is a Composite that looks at two pixels and
retains the darker of the two, so that when the shadows overlap, it will
look like their pixles have been merged together instead of combined.

Thanks for any help.

-Brian

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".
[att1.html]

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Brian Nahas

Pulled the trigger on the send button too soon.

I thought it was relatively complex to implement a composite but I
should have explored it more prior to sending my email. My problem was
fixed by a relatively simple implementation where the alpha values of
the src and dest pixels are compared and the greater is kept. However,
this didn't produce the desired visual effect, so I ended up going with
an implementation that adds the alpha values of the src and dest, but
applies a ceiling value to them. Here's the final implementation of the
compose method for those interested:

public void compose(Raster src,
Raster dstIn,
WritableRaster dstOut) {
int[] srcPixels = new int[4];
int[] dstPixels = new int[4];
for (int x=0; x < dstOut.getWidth(); x++){

for (int y=0; y < dstOut.getHeight(); y++){
src.getPixel(x, y, srcPixels);
dstIn.getPixel(x, y, dstPixels);

dstPixels[3] = dstPixels[3] + srcPixels[3];
if (dstPixels[3] > maxDarkness) {
dstPixels[3] = maxDarkness;
}

dstOut.setPixel(x, y, dstPixels);
}
}
}

Note that you'd have to do much more than that to take the rgb values
into account. In this case I was only working with black so I just
ignored them.

-Brian

-----Original Message-----
From: Discussion list for Java 2D API
[mailto:JAVA2D-INTEREST@JAVA.SUN.COM] On Behalf Of Brian Nahas
Sent: Wednesday, March 31, 2004 12:34 PM
To: JAVA2D-INTEREST@JAVA.SUN.COM
Subject: [JAVA2D] alphacomposite for combining drop shadows

For those that don't want to read my motivation for this email, here's
essentially what I'm looking for: Is there some sort of Composite that
does a comparison of the SRC and DEST pixels and retains the darker of
the two? If not, how would I go about implementing one? Or is there a
better way?

Here's why I'm asking: I'm trying to implement feathered drop shadows
for a number of rectangles and I'm having some difficulty combining the
resulting shadows into a smooth backdrop. For example, let's say I have
a rectangle A. The shadow that A casts is essentially a rounded
rectangle, but instead of using a RoundRectangle2D, I composed the
shadow out of a rectangle of the same size as A in the middle, 4 smaller
rectangles on the sides, top and bottom, and then 4 arcs for the 4
corners:

Arc Rect Arc
Rect Rect Rect
Arc Rect Arc

The rectangle in the middle is then painted black with an alpha value,
and then the 4 sides are painted the same black with a gradient paint
that is reduced heading outwards from the middle rectangle. The 4 arcs
on the corners are painted black with a RadialGradient paint the
lightens as you head outwards from the corner. So what I get for the
shadow is a nice rounded rectangle that is larger than the original with
a gradient paint on the edges that gradually lightens. This looks
great.

The problem arises when I have the rectangle A near or next to another
Rectangle, say B. If I use SRC_OVER as an alpha composite for the
shadow buffer, then the shadows (because they are larger than the
rectangles that cast them) combine as if they are from two light sources
and you get a dark section where they come together. If I use SRC, then
whichever shadow get's drawn second destroys the feathering around the
first shadow because the gradient paint on the edges of the second
shadow overwrites the edges on the first shadow.

So what I'm looking for is a Composite that looks at two pixels and
retains the darker of the two, so that when the shadows overlap, it will
look like their pixles have been merged together instead of combined.

Thanks for any help.

-Brian

========================================================================
=== To unsubscribe, send email to listserv@java.sun.com and include in
the body of the message "signoff JAVA2D-INTEREST". For general help,
send email to listserv@java.sun.com and include in the body of the
message "help".

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".
[att1.html]