【问题标题】:Java - Rubber alpha functionJava - 橡胶阿尔法函数
【发布时间】:2014-02-01 23:50:47
【问题描述】:

我目前正在制作一个绘画程序,并且目前正在实施一个橡胶工具(一个适用于 alpha 颜色的版本)。问题是,我无法通过 mouseDragged 事件绘制不可见的线条,因为它们只会出现在之前的绘画之上......

我在 bImg 上考虑过 setRGB,但它需要 mouseDragged 支持,并且还需要使线条的粗细可变。有人有什么想法吗?

编辑:为什么要投反对票?

【问题讨论】:

  • 我不知道。我没有对你投反对票。在这里 +1 只是为了让您不会因为尝试学习而感到羞耻。
  • 谢谢!我不知道为什么编程“专家”不能让我们菜鸟休息一下……
  • 不要介意投反对票,它们和 reddit 业力一样不重要

标签: java graphics alpha graphics2d


【解决方案1】:

downwote 可能与以下事实有关: 您尝试达到什么目标,以及 如何 您已经尝试过了。

我假设您想在mouseDragged 中的图像上画线。这些线条应该具有“橡皮”/“橡皮擦”的效果,删除一些先前绘制的像素,或者(当你说你想要一个 alpha 值时),也许不是删除它们,但只会让它们变得更苍白。使用 setRGB 手动更改像素值不是一种选择,因为这种橡胶效果应该具有一定的厚度,您可能通过在调用graphics.draw(rubberLine) 之前设置graphics.setStroke(new BasicStroke(thickness)) 来选择它。

如果这一切都正确,那么您可能必须使用 http://docs.oracle.com/javase/6/docs/api/java/awt/Graphics2D.html#setComposite%28java.awt.Composite%29 设置适当的组合。特别是,您必须设置一个 AlphaComposite (http://docs.oracle.com/javase/6/docs/api/java/awt/AlphaComposite.html)。您可能会尝试不同的方法来实现不同的“橡胶效果”,具体取决于已擦除像素具有的 alpha 值,以及您为“橡胶颜色”设置的 alpha 值。

编辑:一个例子,......也许你应该更清楚地描述问题

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();
    }
}

【讨论】:

  • 试过复合,没用;我目前正在测试光栅方法。不过感谢您的帮助。
  • 该代码不正确,因为您不能使用具有 alpha 值的线来绘制不透明的线。反正问题已经解决了。
  • 显然可以。或者你认为上面的代码做了什么?
【解决方案2】:

您可以将图像转换为writeableraster,并在特定条件下使用 getpixel() 和 setpixel() 方法转换用户鼠标指针下方的颜色。

【讨论】:

  • 谢谢,但是我可以对这个方法应用厚度吗?
  • 这种方法需要您通过对用户单击的像素两侧的给定数量的像素应用任何颜色操作来滚动自己的厚度。可能需要一些编码,但它可以工作。
猜你喜欢
  • 1970-01-01
  • 2017-09-05
  • 2014-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
相关资源
最近更新 更多