J. Carter
J. Carter

Reputation: 3

How do I fade the edges of an image in Java? (example given)

I am currently in the middle of a project in which I have to grayscale, blue filter, red filter, green filter, and fade the edges of a picture of a cat at the press of a JButton. grayscale and color filtering the picture was easy, but I can't seem to figure out how to fade the image's edges to black.

What I mean by this, is I have this picture of the cat I need to change:

the cat I need to change

and I need to change it into something like this one:

this one.

    import javax.imageio.ImageIO;
    import javax.swing.JButton;
    import javax.swing.JPanel;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.ImageIcon;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException; 

    public class GUIKittenPicJC {
        public static class KittenChanger extends JPanel {
                BufferedImage img = null;
                File Kitten = null;
                ImageIcon imagetransformed = null;
                JButton grayscale = new JButton("Grayscale Image");
                JButton rgbB = new JButton("Blue filter this image");
                JButton rgbR = new JButton("Red filter this image");
                JButton rgbG = new JButton("Green filter this image");
                JButton fader = new JButton("Fade this image");
                {
                try
                {
                    Kitten = new File("C:\\Users\\Jarrod\\Desktop\\Lab 3\\Lab 3\\kitten.bmp");
                    img = ImageIO.read(Kitten);
                }
                catch(IOException e)
                {
                  System.out.println(e);
                }
            ImageIcon image = new ImageIcon(img);
            JLabel imageLabel = new JLabel(image);
            add(imageLabel);
            grayscale.addActionListener(e->{
                       imagetransformed = new ImageIcon(Grayscale(img));
                       imageLabel.setIcon(imagetransformed);
                       imgReset();
                    });
            rgbB.addActionListener(e->{
                   imagetransformed = new ImageIcon(Bluify(img));
                   imageLabel.setIcon(imagetransformed);
                   imgReset();
                });
            rgbG.addActionListener(e->{
                   imagetransformed = new ImageIcon(Greenify(img));
                   imageLabel.setIcon(imagetransformed);
                   imgReset();
                });
            rgbR.addActionListener(e->{
                   imagetransformed = new ImageIcon(Redify(img));
                   imageLabel.setIcon(imagetransformed);
                   imgReset();
                });
                        add(grayscale);
                        add(rgbB);
                        add(rgbG);
                        add(rgbR);
                }
                private void imgReset() {
                    try {
                            img = ImageIO.read(Kitten);
                        } 
                    catch (IOException e1)
                        {
                            e1.printStackTrace();
                        }
                }

        }
        public static void main(String[] args)
        {
           createGUI();
          }
            private static void createGUI() {


                JFrame frame = new JFrame("Kitten Changer");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                KittenChanger newContentPane = new KittenChanger();
                newContentPane.setOpaque(true);
                frame.setContentPane(newContentPane);
                frame.setSize(400, 500);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

//Grayscale and rgb filter methods follow, not important to question
}

How would I create a method for this sort of filter and properly apply it to a button like the others?

Upvotes: 0

Views: 327

Answers (1)

kirtan-shah
kirtan-shah

Reputation: 473

You would have to edit each of the pixels individually. The main idea of this solution is that you have the center of an image, and each pixel is changed as a function of the distance to the center.

More simply put, pixels farther from the center will be made darker.

This is what your code would look like:

BufferedImage cat; //assuming it is assigned
for(int i = 0; i < cat.getWidth(); i++) { // i is the x coord
    for(int j = 0; j < cat.getHeight(); j++) { // j is the y coord
        int color = cat.getRGB(i, j);
        int r = (color >> 16) & 0xff; //extract red value
        int g = (color >> 8) & 0xff;
        int b = color & 0xff;
        double scale = 0.75; /**** Change this to change the resulting effect ****/
        //pixel's distance from center
        double dist = Math.sqrt( Math.pow(i - cat.getWidth()/2, 2) + Math.pow(j - cat.getHeight()/2, 2) );
        r = (int) Math.max(0, r - dist*scale); //r - dist*scale makes px darker
        g = (int) Math.max(0, g - dist*scale); //Math.max makes sure r is always >= 0
        b = (int) Math.max(0, b - dist*scale);
        int newRGB = (r << 16) + (g << 8) + b; //convert r,g,b to single int
        cat.setRGB(i, j, newRGB); //finally, update rgb value
    }

}


And, when I ran this code:
enter image description here

Remember, you can always change the effect by changing the scale variable in the code above.

Upvotes: 1

Related Questions