Question

I am currently making a paint program, and am currently implementing a rubber tool (a version which works with alpha colors). The problem is, I can't paint invisible lines via mouseDragged event because they will just go on top of the painting that was there before...

I have considered setRGB on bImg, but it would need to be supported by mouseDragged and also make the thickness of the line variable. Anyone got any ideas?

EDIT: Why down votes?

Was it helpful?

Solution 2

You could convert your image to a writeableraster and use getpixel() and setpixel() methods to convert the colors underneath the user's mouse-pointer under certain conditions.

OTHER TIPS

The downwote might be related to the fact it is not entirely clear what you try to achive, and how you already tried it.

I assume that you want to draw lines over your image in mouseDragged. These lines should have the effect of a "rubber"/"eraser", removing some of the previously painted pixels, or (when you say that you want to have an alpha value), maybe not removing them, but just making them more pale. Changing the pixel values manually with setRGB is not an option, because this rubber-effect should have a certain thickness, that you probably selected by setting an graphics.setStroke(new BasicStroke(thickness)) before calling graphics.draw(rubberLine).

IF this is all correct, then you will probably have to set an appropriate composite, using http://docs.oracle.com/javase/6/docs/api/java/awt/Graphics2D.html#setComposite%28java.awt.Composite%29 . Particularly, you will have to set an AlphaComposite ( http://docs.oracle.com/javase/6/docs/api/java/awt/AlphaComposite.html ). You might try out different ones to achieve different "rubber effects", depending on the alpha value that the erased pixels have, and depending on the alpha value that you set for the "rubber color".

EDIT: An example, ... maybe you should describe the problem more clearly

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class SimplePaint
{
    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);

        PaintPanel paintPanel = new PaintPanel();

        f.getContentPane().setLayout(new BorderLayout());
        f.getContentPane().add(
            createControlPanel(paintPanel), BorderLayout.NORTH);
        f.getContentPane().add(paintPanel, BorderLayout.CENTER);

        f.setSize(500,500);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    static JPanel createControlPanel(final PaintPanel paintPanel)
    {
        JPanel controlPanel = new JPanel(new GridLayout(0,2));
        final JLabel label = new JLabel("Paint");
        final JSlider slider = new JSlider(0, 255, 0);
        slider.addChangeListener(new ChangeListener()
        {

            @Override
            public void stateChanged(ChangeEvent e)
            {
                int value = slider.getValue();
                if (value <= 0)
                {
                    label.setText("Paint");
                }
                else
                {
                    label.setText("Rubber alpha "+value);
                }
                paintPanel.setRubber(value);
            }
        });
        controlPanel.add(label);
        controlPanel.add(slider);
        return controlPanel;
    }
}



class PaintPanel extends JPanel implements MouseMotionListener
{
    private BufferedImage image;
    private Point previousPoint = new Point();
    private int rubberAlpha = -1;

    PaintPanel()
    {
        addMouseMotionListener(this);
    }

    void setRubber(int alpha)
    {
        this.rubberAlpha = alpha;
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        int w = getWidth();
        int h = getHeight();
        if (image == null)
        {
            image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            Graphics imageG = image.getGraphics();
            imageG.setColor(Color.WHITE);
            imageG.fillRect(0, 0, w, h);
            imageG.dispose();
        }
        else if (image.getWidth() != w || image.getHeight() != h)
        {
            BufferedImage newImage = 
                new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            Graphics imageG = newImage.getGraphics();
            imageG.drawImage(image, 0, 0, null);
            imageG.dispose();
            image = newImage;
        }
        g.drawImage(image, 0, 0, null);
    }

    @Override
    public void mouseDragged(MouseEvent e)
    {
        if (image == null)
        {
            return;
        }

        Graphics2D g = (Graphics2D)image.getGraphics();
        g.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING, 
            RenderingHints.VALUE_ANTIALIAS_ON);

        if (rubberAlpha > 0)
        {
            g.setColor(new Color(255,255,255,rubberAlpha));
            Line2D line = new Line2D.Double(previousPoint, e.getPoint());
            g.setStroke(new BasicStroke(20, 
                BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g.draw(line);
        }
        else
        {
            g.setColor(new Color(255,0,0,255));
            Line2D line = new Line2D.Double(previousPoint, e.getPoint());
            g.setStroke(new BasicStroke(20, 
                BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g.draw(line);
        }

        g.dispose();
        repaint();

        previousPoint = e.getPoint();
    }

    @Override
    public void mouseMoved(MouseEvent e)
    {
        previousPoint = e.getPoint();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top