shaded BufferedImage Hexagon - Java 2D Graphics

Java examples for 2D Graphics:BufferedImage Effect

Description

shaded BufferedImage Hexagon

Demo Code


import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Polygon;
import java.awt.RadialGradientPaint;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import org.apache.log4j.Logger;

public class Main{
    private static final int HEXRADIUS = 32;
    public BufferedImage original;
    public static BufferedImage shadedHexagon(BufferedImage in) {
        BufferedImage result = new BufferedImage((int) (HEXRADIUS
                * Math.sqrt(3.0) + 6), (int) (HEXRADIUS * 2 + 5),
                BufferedImage.TYPE_INT_ARGB);

        Graphics2D gr = result.createGraphics();
        gr.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                RenderingHints.VALUE_INTERPOLATION_BILINEAR);

        gr.drawImage(in, 0, 0, result.getWidth(), result.getHeight(),
                0 /*sx1*/, 0 /*sy1*/, in.getWidth() /* sx2 */,
                in.getHeight() /* sy2 */, null);

        Area mask = new Area(new Rectangle(0, 0, result.getWidth(),
                result.getHeight()));/*from  w w w.  ja  va  2 s . c o  m*/
        // create the clipping hexagon shape
        int midx = result.getWidth() / 2;
        int midy = result.getHeight() / 2;
        int dx = (int) Math.round(HEXRADIUS * Math.sqrt(3.0) / 2.0);
        int dy = HEXRADIUS / 2;

        int[][] hexOutline = { { midx, midy - HEXRADIUS },
                { midx + dx, midy - dy }, { midx + dx, midy + dy },
                { midx, midy + HEXRADIUS }, { midx - dx, midy + dy },
                { midx - dx, midy - dy } };

        Polygon hex = new Polygon();
        for (int[] point : hexOutline) {
            hex.addPoint(point[0], point[1]);
        }

        mask.subtract(new Area(hex));

        gr.setColor(Color.WHITE);
        gr.setComposite(AlphaComposite.Clear);

        gr.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        // Clear the cut out area
        gr.fill(mask);

        // light grey overlay on left side
        Polygon cubeFaceLeft = new Polygon();
        cubeFaceLeft.addPoint(midx - dx, midy - dy);
        cubeFaceLeft.addPoint(midx, midy);
        cubeFaceLeft.addPoint(midx, midy + HEXRADIUS);
        cubeFaceLeft.addPoint(midx - dx, midy + dy);
        mask = new Area(cubeFaceLeft);

        gr.setColor(new Color(100, 100, 100, 180));
        gr.setComposite(AlphaComposite.SrcOver);

        gr.fill(mask);

        // darker grey overlay on right side
        Polygon cubeFaceRight = new Polygon();
        cubeFaceRight.addPoint(midx + dx, midy - dy);
        cubeFaceRight.addPoint(midx, midy);
        cubeFaceRight.addPoint(midx, midy + HEXRADIUS);
        cubeFaceRight.addPoint(midx + dx, midy + dy);
        mask = new Area(cubeFaceRight);

        gr.setColor(new Color(50, 50, 50, 180));
        gr.fill(mask);

        // some lines
        gr.setColor(Color.black);
        gr.setStroke(new BasicStroke(0.8f));
        //gr.drawLine(midx, midy, midx-dx, midy-dy);
        //gr.drawLine(midx, midy, midx+dx, midy-dy);
        //gr.drawLine(midx, midy, midx, midy+HEXRADIUS);

        // outline
        for (int i = 0; i < 6; i++) {
            // gr.drawLine( hexOutline[i][0], hexOutline[i][1],
            //      hexOutline[(i+1)%6][0], hexOutline[(i+1)%6][1]);
        }
        gr.dispose();

        // some drop shadow
        result = dropShadow(result, 4);
        return result;
    }
    public BufferedImage shadedHexagon() {
        return shadedHexagon(original);
    }
    public static BufferedImage dropShadow(BufferedImage in, int shadowWidth) {

        // move bottom right
        // gray the image, 
        // blur it a bit
        // paint over original

        BufferedImage result = new BufferedImage(in.getWidth()
                + shadowWidth, in.getHeight() + shadowWidth,
                BufferedImage.TYPE_INT_ARGB);

        Graphics2D g = result.createGraphics();
        g.drawImage(in, shadowWidth >> 1, shadowWidth >> 1, null);
        // g.drawImage(in, 0, 0, null);

        // now gray out the image, keep alpha
        int[] pixels = new int[result.getWidth() * result.getHeight()];
        result.getRGB(0, 0, result.getWidth(), result.getHeight(), pixels,
                0 /*offset*/, result.getWidth() /*scansize */);

        for (int i = 0; i < pixels.length; i++) {
            // keep only alpha channel and some grey
            pixels[i] = (pixels[i] & (0xff000000)) | 0x00505050;
        }
        result.setRGB(0, 0, result.getWidth(), result.getHeight(), pixels,
                0 /*offset*/, result.getWidth() /*scansize */);
        g.dispose();

        // blur the opaque gray into the transparent surrounding
        result = getGaussianBlurFilter((int) (shadowWidth * 1.2), true)
                .filter(result, null);
        result = getGaussianBlurFilter((int) (shadowWidth * 1.2), false)
                .filter(result, null);
        g = result.createGraphics();
        g.drawImage(in, 0, 0, null);

        g.dispose();
        return result;
    }
    public static ConvolveOp getGaussianBlurFilter(int radius,
            boolean horizontal) {
        if (radius < 1) {
            throw new IllegalArgumentException("Radius must be >= 1");
        }

        int size = radius * 2 + 1;
        float[] data = new float[size];

        float sigma = radius / 3.0f;
        float twoSigmaSquare = 2.0f * sigma * sigma;
        float sigmaRoot = (float) Math.sqrt(twoSigmaSquare * Math.PI);
        float total = 0.0f;

        for (int i = -radius; i <= radius; i++) {
            float distance = i * i;
            int index = i + radius;
            data[index] = (float) Math.exp(-distance / twoSigmaSquare)
                    / sigmaRoot;
            total += data[index];
        }

        for (int i = 0; i < data.length; i++) {
            data[i] /= total;
        }

        Kernel kernel = null;
        if (horizontal) {
            kernel = new Kernel(size, 1, data);
        } else {
            kernel = new Kernel(1, size, data);
        }
        return new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
    }
}

Related Tutorials