Question

How can I make an image border as gradient. I googled a lot, but didn't find correct suggestion. Any one can help me...

Existing image

Modified image

Any suggestion please...

Was it helpful?

Solution

This is an interesting one. I first thought that there should be a simple solution, using some Graphics#drawRoundRect call with the appropriate Paint, but it's not sooo simple.

However, one solution is implemented in the following example:

The image is painted as-it-is into a new image. Then the edges and corners are painted. These consist of rectangles. Each rectangle for one edge is filled with a GradientPaint that interpolates between "completely transparent" and "completely opaque". Similarily, the rectangles for the corners are filled with a RadialGradientPaint interpolating between the same colors. These are painted with the AlphaComposite.DstOut composition rule, so that the actual pixels of the image are slowly "blending out" towards the border.

enter image description here

(The checkerboard pattern is only painted in the background of the component, to emphasize that it iterpolates towards transparent pixels at the border)

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.RadialGradientPaint;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class BorderBlurTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        BufferedImage input = null;
        try
        {
            input = ImageIO.read(new File("KCR0B.jpg"));
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        BufferedImage output = blurBorder(input, 20);
        f.getContentPane().setLayout(new GridLayout());
        f.getContentPane().add(new ImagePanel(input));
        f.getContentPane().add(new ImagePanel(output));
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static BufferedImage blurBorder(BufferedImage input, double border)
    {
        int w = input.getWidth();
        int h = input.getHeight();
        BufferedImage output = new BufferedImage(
            w, h, BufferedImage.TYPE_INT_ARGB);

        Graphics2D g = output.createGraphics();
        g.drawImage(input, 0, 0, null);

        g.setComposite(AlphaComposite.DstOut);
        Color c0 = new Color(0,0,0,255);
        Color c1 = new Color(0,0,0,0);

        double cy = border;
        double cx = border;

        // Left
        g.setPaint(new GradientPaint(
            new Point2D.Double(0, cy), c0,
            new Point2D.Double(cx,cy), c1));
        g.fill(new Rectangle2D.Double(
            0, cy, cx, h-cy-cy));

        // Right
        g.setPaint(new GradientPaint(
            new Point2D.Double(w-cx, cy), c1,
            new Point2D.Double(w,cy), c0));
        g.fill(new Rectangle2D.Double(
            w-cx, cy, cx, h-cy-cy));

        // Top
        g.setPaint(new GradientPaint(
            new Point2D.Double(cx, 0), c0,
            new Point2D.Double(cx, cy), c1));
        g.fill(new Rectangle2D.Double(
            cx, 0, w-cx-cx, cy));

        // Bottom
        g.setPaint(new GradientPaint(
            new Point2D.Double(cx, h-cy), c1,
            new Point2D.Double(cx, h), c0));
        g.fill(new Rectangle2D.Double(
            cx, h-cy, w-cx-cx, cy));


        // Top Left
        g.setPaint(new RadialGradientPaint(
            new Rectangle2D.Double(0, 0, cx+cx, cy+cy),
            new float[]{0,1}, new Color[]{c1, c0}, CycleMethod.NO_CYCLE));
        g.fill(new Rectangle2D.Double(0, 0, cx, cy));

        // Top Right
        g.setPaint(new RadialGradientPaint(
            new Rectangle2D.Double(w-cx-cx, 0, cx+cx, cy+cy),
            new float[]{0,1}, new Color[]{c1, c0}, CycleMethod.NO_CYCLE));
        g.fill(new Rectangle2D.Double(w-cx, 0, cx, cy));

        // Bottom Left
        g.setPaint(new RadialGradientPaint(
            new Rectangle2D.Double(0, h-cy-cy, cx+cx, cy+cy),
            new float[]{0,1}, new Color[]{c1, c0}, CycleMethod.NO_CYCLE));
        g.fill(new Rectangle2D.Double(0, h-cy, cx, cy));

        // Bottom Right
        g.setPaint(new RadialGradientPaint(
            new Rectangle2D.Double(w-cx-cx, h-cy-cy, cx+cx, cy+cy),
            new float[]{0,1}, new Color[]{c1, c0}, CycleMethod.NO_CYCLE));
        g.fill(new Rectangle2D.Double(w-cx, h-cy, cx, cy));

        g.dispose();

        return output;
    }


    static class ImagePanel extends JPanel
    {
        private final BufferedImage image;

        ImagePanel(BufferedImage image)
        {
            this.image = image;
        }

        @Override
        public Dimension getPreferredSize()
        {
            if (super.isPreferredSizeSet())
            {
                return super.getPreferredSize();
            }
            return new Dimension(image.getWidth(), image.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            int s = 8;
            int w = getWidth();
            int h = getHeight();
            for (int x=0; x<w; x++)
            {
                for (int y=0; y<h; y++)
                {
                    if (((x+y) & 1) == 0)
                    {
                        g.setColor(Color.WHITE);
                    }
                    else
                    {
                        g.setColor(Color.LIGHT_GRAY);
                    }
                    g.fillRect(x*s,y*s,s,s);
                }
            }
            g.drawImage(image, 0, 0, null);
        }
    }

}

OTHER TIPS

Create a transparent image of the same size, draw the white border and blur it. Than copy it on top of the image that you want to have the gradient border on.

Reference: http://www.jhlabs.com/ip/blurring.html

Hope that helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top