package co.forsaken.projectindigo.utils;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.awt.image.Kernel;
import java.awt.image.RGBImageFilter;
import java.lang.ref.SoftReference;
public class DrawingUtils {
public static BlurUtils getBlurUtils() {
return new BlurUtils();
}
public static class BlurUtils {
private static SoftReference<BufferedImage> _buffer0;
private static SoftReference<BufferedImage> _buffer1;
public BufferedImage applyGaussianBlur(BufferedImage image, int filterRadius, float alphaFactor, boolean useOriginalImageAsDestination) {
if (filterRadius < 1) { throw new IllegalArgumentException("Illegal filter radius: expected to be >= 1, was " + filterRadius); }
float[] kernel = new float[2 * filterRadius + 1];
float sigma = filterRadius / 3.0F;
float alpha = 2.0F * sigma * sigma;
float rootAlphaPI = (float) Math.sqrt(alpha * 3.141592653589793D);
float sum = 0.0F;
for (int i = 0; i < kernel.length; i++) {
int d = -((i - filterRadius) * (i - filterRadius));
kernel[i] = (float) (Math.exp(d / alpha) / rootAlphaPI);
sum += kernel[i];
}
for (int i = 0; i < kernel.length; i++) {
kernel[i] /= sum;
kernel[i] *= alphaFactor;
}
Kernel horizontalKernel = new Kernel(kernel.length, 1, kernel);
Kernel verticalKernel = new Kernel(1, kernel.length, kernel);
synchronized (BlurUtils.class) {
int blurredWidth = useOriginalImageAsDestination ? image.getWidth() : image.getWidth() + 4 * filterRadius;
int blurredHeight = useOriginalImageAsDestination ? image.getHeight() : image.getHeight() + 4 * filterRadius;
BufferedImage img0 = ensureBuffer0Capacity(blurredWidth, blurredHeight);
Graphics2D graphics0 = img0.createGraphics();
graphics0.drawImage(image, null, useOriginalImageAsDestination ? 0 : 2 * filterRadius, useOriginalImageAsDestination ? 0
: 2 * filterRadius);
graphics0.dispose();
BufferedImage img1 = ensureBuffer1Capacity(blurredWidth, blurredHeight);
Graphics2D graphics1 = img1.createGraphics();
graphics1.drawImage(img0, new ConvolveOp(horizontalKernel, 1, null), 0, 0);
graphics1.dispose();
BufferedImage destination = useOriginalImageAsDestination ? image : new BufferedImage(blurredWidth, blurredHeight, 2);
Graphics2D destGraphics = destination.createGraphics();
destGraphics.drawImage(img1, new ConvolveOp(verticalKernel, 1, null), 0, 0);
destGraphics.dispose();
return destination;
}
}
private static BufferedImage ensureBuffer0Capacity(int width, int height) {
BufferedImage img0 = _buffer0 != null ? (BufferedImage) _buffer0.get() : null;
img0 = ensureBufferCapacity(width, height, img0);
_buffer0 = new SoftReference<BufferedImage>(img0);
return img0;
}
private static BufferedImage ensureBuffer1Capacity(int width, int height) {
BufferedImage img1 = _buffer1 != null ? (BufferedImage) _buffer0.get() : null;
img1 = ensureBufferCapacity(width, height, img1);
_buffer1 = new SoftReference<BufferedImage>(img1);
return img1;
}
private static BufferedImage ensureBufferCapacity(int width, int height, BufferedImage img) {
if ((img == null) || (img.getWidth() < width) || (img.getHeight() < height)) {
img = new BufferedImage(width, height, 2);
} else {
Graphics2D g2 = img.createGraphics();
g2.setComposite(AlphaComposite.Clear);
g2.fillRect(0, 0, width, height);
g2.dispose();
}
return img;
}
}
public static BufferedImage roundCorners(BufferedImage src, int radius) {
int w = src.getWidth();
int h = src.getHeight();
int type = BufferedImage.TYPE_INT_ARGB;
BufferedImage dst = new BufferedImage(w, h, type);
Graphics2D g2 = dst.createGraphics();
RoundRectangle2D r2 = new RoundRectangle2D.Double(0, 0, w, h, radius, radius);
g2.setClip(r2);
g2.drawImage(src, 0, 0, null);
g2.dispose();
return dst;
}
public static BufferedImage overlayImage(BufferedImage under, BufferedImage over) {
BufferedImage dest = under;
Graphics2D g2 = dest.createGraphics();
g2.drawImage(over.getScaledInstance(under.getWidth(), under.getHeight(), 4), 0, 0, null);
g2.dispose();
return dest;
}
public static BufferedImage makeColorTransparent(BufferedImage im, final Color color) {
ImageFilter filter = new RGBImageFilter() {
public int markerRGB = color.getRGB() | 0xFFFF0000;
public final int filterRGB(int x, int y, int rgb) {
if ((rgb | 0xFF000000) == markerRGB) {
return 0x00FFFFFF & rgb;
} else {
return rgb;
}
}
};
ImageProducer ip = new FilteredImageSource(im.getSource(), filter);
return getBI(Toolkit.getDefaultToolkit().createImage(ip));
}
private static BufferedImage getBI(Image image) {
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = bufferedImage.createGraphics();
g2.drawImage(image, 0, 0, null);
g2.dispose();
return bufferedImage;
}
}