Fixed #1914 DropShadow filter

This commit is contained in:
Jindra Petřík
2022-12-27 19:25:01 +01:00
parent 0c4adb7d1a
commit b7c5efbf93
2 changed files with 32 additions and 11 deletions
@@ -399,6 +399,14 @@ public class Filtering {
return val;
}
private static Color over(Color a, Color b) {
int resultA = a.getAlpha() + b.getAlpha() * (255 - a.getAlpha()) / 255;
int resultR = cut((a.getRed() * (a.getAlpha() / 255.0) + b.getRed() * (b.getAlpha() / 255.0) * (1 - (a.getAlpha() / 255.0))) / (resultA / 255.0));
int resultG = cut((a.getGreen() * (a.getAlpha() / 255.0) + b.getGreen() * (b.getAlpha() / 255.0) * (1 - (a.getAlpha() / 255.0))) / (resultA / 255.0));
int resultB = cut((a.getBlue() * (a.getAlpha() / 255.0) + b.getBlue() * (b.getAlpha() / 255.0) * (1 - (a.getAlpha() / 255.0))) / (resultA / 255.0));
return new Color(resultR, resultG, resultB, resultA);
}
private static BufferedImage dropShadow(BufferedImage src, int blurX, int blurY, float angle, double distance, Color color, boolean inner, int iterations, float strength, boolean knockout, boolean compositeSource) {
int width = src.getWidth();
int height = src.getHeight();
@@ -408,38 +416,48 @@ public class Filtering {
int alpha = (srcPixels[i] >> 24) & 0xff;
if (inner) {
alpha = 255 - alpha;
}
shadow[i] = RGBA.toInt(color.getRed(), color.getGreen(), color.getBlue(), cut(color.getAlpha() * alpha / 255 * strength));
}
Color shadowColor;
shadowColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), cut(color.getAlpha() * alpha / 255 * strength));
shadow[i] = shadowColor.getRGB();
}
Color colorFirst = Color.BLACK;
Color colorAlpha = ALPHA;
double angleRad = angle / 180 * Math.PI;
double moveX = (distance * Math.cos(angleRad));
double moveY = (distance * Math.sin(angleRad));
shadow = moveRGB(width, height, shadow, moveX, moveY, inner ? colorFirst : colorAlpha);
shadow = moveRGB(width, height, shadow, moveX, moveY, inner ? color : colorAlpha);
if (blurX > 0 || blurY > 0) {
blur(shadow, width, height, blurX, blurY, iterations, null);
}
if (compositeSource) {
if (knockout || inner) {
for (int i = 0; i < shadow.length; i++) {
int mask = (srcPixels[i] >> 24) & 0xff;
if (!inner) {
mask = 255 - mask;
}
shadow[i] = shadow[i] & 0xffffff + ((mask * ((shadow[i] >> 24) & 0xff) / 255) << 24);
if (inner && compositeSource && !knockout) {
Color shadowColor = new Color(shadow[i], true);
Color srcColor = new Color(srcPixels[i], true);
srcColor = new Color(srcColor.getRed(), srcColor.getGreen(), srcColor.getBlue(), 255);
Color resultColor = over(shadowColor, srcColor);
shadow[i] = resultColor.getRGB();
}
shadow[i] = (shadow[i] & 0xffffff) + ((mask * ((shadow[i] >> 24) & 0xff) / 255) << 24);
}
}
BufferedImage retCanvas = new BufferedImage(width, height, src.getType());
setRGB(retCanvas, width, height, shadow);
if (!knockout && compositeSource) {
if (!knockout && compositeSource && !inner) {
Graphics2D g = retCanvas.createGraphics();
g.setComposite(AlphaComposite.DstOver);
g.setComposite(AlphaComposite.SrcOver);
g.drawImage(src, 0, 0, null);
}
@@ -587,7 +605,7 @@ public class Filtering {
}
private static int cut(double val) {
int i = (int) val;
int i = (int) Math.round(val);
if (i < 0) {
i = 0;
}