2

I want to make a small program that allows you to change the Alpha chanel of selected pixels of an image. think the eraser tool on photoshop. So, I got the program to draw a color on the image, and tried using setRGB(0x00000000,0x00000000,0x00000000) to set the pixel to alpha 0; no dice, just paints black.

I've also tried painting a blue oval (which works great) so I know my mouse listener is working. (thats commented out in the code)

Now I am taking the raster of that image and trying to modify the alpha chanel using setPixels(), or setRect(), but I can't seem to get it to work. I m thinking my problem is with the Array you have to pass. I assume its a 10 x 10 pixel array and 4 channels so the array has to be length 400.

Its my first time trying this, so my code is kinda ugly with alot of stuff commented out, because I've tried about a million ways of doing this; but here it is.

Thanks for any help in advance.

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;

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

public class MyFrame extends JFrame implements MouseListener,
    MouseMotionListener {

    BufferedImage myImage = new BufferedImage(300, 300,
        BufferedImage.TYPE_INT_ARGB);
    BufferedImage blankImage = new BufferedImage(10, 10,
        BufferedImage.TYPE_INT_ARGB);
    File myPNG = new File("output.png");
    MyPanel mp = new MyPanel();
    File tempPNG = new File("temp.png");
    File initialFile = new File("test.jpg");
    Color blankColor = new Color(0, 0, 0, .0f);
    int diameter = 10;
    int mouseX = 0;
    int mouseY = 0;
    boolean mouseClicked = false;
    boolean fileCreated;
    WritableRaster myRaster;
    WritableRaster blankRaster;
    int[] emptySquare = new int[400];
    ColorModel colorModel = myImage.getColorModel();

    public MyFrame() {
        setLayout(new BorderLayout());
        setSize(800, 800);
        add(mp, BorderLayout.EAST);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
        setFocusable(true);
        addMouseListener(this);
        addMouseMotionListener(this);
        for (int x = 0; x < 10; x++) {
            for (int y = 0; y < 10; y++) {
                for (int b = 0; b < 4; b++) {

                    emptySquare[x * y * b] = 0x00000000;
                }
            }
        }
        myRaster = myImage.getRaster();
        blankRaster = blankImage.getRaster();

        try {

            myImage = ImageIO.read(initialFile);
            fileCreated = ImageIO.write(myImage, "png", tempPNG);
            myImage = ImageIO.read(tempPNG);

        } catch (Exception e) {
        }
    }

    public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;

        g2d.setColor(Color.BLACK);
        // g2d.fillRect(0, 0, 300, 300);
        g2d.drawImage(myImage, 0, 0, 300, 300, null);

        // g2d.setColor(blankColor);
        // g2d.setPaint(Color.blue);

        // myImage.
    }

    private class MyPanel extends JPanel {

        private MyPanel() {
        }
    }

    @Override
    public void mouseClicked(MouseEvent m) {

        repaint();

    }

    @Override
    public void mouseEntered(MouseEvent m) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mouseExited(MouseEvent m) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mousePressed(MouseEvent m) {

        repaint();

    }

    @Override
    public void mouseReleased(MouseEvent m) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mouseDragged(MouseEvent m) {

        mouseX = m.getX();
        mouseY = m.getY();

        myRaster.setDataElements(mouseX, mouseY, blankRaster);
        myImage = new BufferedImage(colorModel, myRaster, true, null);
        myImage.setData(blankRaster);

        myRaster.setPixel(mouseX, mouseY, emptySquare);
        myImage.setData(blankRaster);
        AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .1f);
        Graphics2D tempG2d = myImage.createGraphics();
        tempG2d.setComposite(AlphaComposite.Clear);
        // tempG2d.setColor(Color.blue);

        tempG2d.fillOval(mouseX, mouseY, diameter, diameter);

        // tempG2d.setColor(blankColor);
        // tempG2d.setComposite(AlphaComposite.Src);

        for (int i = mouseX; i < mouseX + diameter; i++) {
            for (int j = mouseY; j < mouseY + diameter; j++) {
                int white = 0xffffff;

                Color c = new Color(0xccFF0000, true);
                int color = myImage.getRGB(i, j) & 0x00ffffff; // use bitwise &
                // to remove
                // alpha
                // component
                myRaster.setPixel(mouseX, mouseY, emptySquare);
                myImage.setData(myRaster);

                // myImage.setRGB(i,j,color); // transparent white

            }

        }

        // tempG2d.fillOval(mouseX, mouseY, diameter, diameter);
        try {
            // fileCreated=ImageIO.write(myImage, "png", tempPNG);
        } catch (Exception e) {
        }
        repaint();
    }

    @Override
    public void mouseMoved(MouseEvent arg0) {
        // TODO Auto-generated method stub
    }
}
skaffman
  • 398,947
  • 96
  • 818
  • 769
JGillikin
  • 21
  • 2

1 Answers1

3

Instead, use getPixel() on the underlying Raster, clear the alpha byte, and update the image using setPixel() and the updated array. See also this related example.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • maybe used paint() for JFrame too +1 – mKorbel Feb 21 '12 at 21:10
  • @mKorbel: is right; this [example](http://stackoverflow.com/a/2901472/230513) that extends `JPanel` and override's `paintComponent()` may be convenient for experimenting. – trashgod Feb 22 '12 at 02:45
  • I just used paint because it was a JFrame and not a JPanel... I am a little confused on how to clear the alpha byte... 1) are you using AlphaComposite.Clear? or using 0x00000000 as the integer value for each channel? 2)I also don't understand what is supposed to be in the [] passed into the array. 3) how do you determine the length of the array. – JGillikin Feb 22 '12 at 03:12
  • Actually, I just added `img.setRGB(x, y, 0); repaint();` to the mouse listener in [`Grid`](http://stackoverflow.com/a/2901472/230513). Filling the panel with some color in `paintComponent()` makes it a little easier to see. – trashgod Feb 22 '12 at 03:21
  • I tried img.setRGB(x,y,0) before and it just drew black on my image, which was odd because I thought that it would account for the alpha chanel, so I assumed set RGB didn't work for type ARGB. do you know the answer to questions 1,2, and 3 above if I wanted to do the raster.setPixels() way? Thanks for all the help – JGillikin Feb 22 '12 at 03:33
  • The revisions above to the `Grid` example work; update your question with the new code, so we're on teh same page. – trashgod Feb 22 '12 at 04:13