0

言語:Java。

こんにちは、Graphics2Dの同じ場所に複数回描画しないようにする必要があります。たとえば、ユーザーが特定の領域に丸いキャップと幅10のBasicStrokeを使用して描画した場合、その同じ領域を2回目に描画することはできません。

これを実行したい理由は、ユーザーが同じストロークで描画することなく、画像上に(フリーハンドで)半透明の色を描画できるようにするためです(したがって、色の密度を上げて半透明を減らします)。

ユーザーが作成したすべてのストロークの形状を(形状を差し引くAreaオブジェクトとして)保存してから、それらすべてのAreaオブジェクトの交差によってGraphics2Dをクリップしてみました。

これはほぼ機能しますが、クリップによって取得される「形状」は、ストロークによって描画される「形状」とまったく同じではありません。数ピクセル離れています。

誰かがうまくいくかもしれない他のアイデアを持っていますか?

4

1 に答える 1

2

コンセプトは比較的単純で、レンダリングできる複数のレイヤーが必要です...

問題に取り組むには複数の異なる方法があります。のリストを維持し、Point各ペイントサイクルで、これらのポイントをバッキングバッファーにレンダリングし、それを使用してメインコンテンツを描画することができますAlphaComposite

(この例のように)バッキングバッファーとrepaintコンテンツに直接描画することもできます。この場合も、を使用しAlphaCompositeて上位レイヤーをレンダリングします。

レイヤーはいくつでも構いません...

ここに画像の説明を入力してください

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;

public class PaintOver {

    public static void main(String[] args) {
        new PaintOver();
    }

    public PaintOver() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new MapPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

            }
        });
    }

    public class MapPane extends JPanel {

        private BufferedImage background;
        private BufferedImage foreground;

        public MapPane() {
            try {
                background = ImageIO.read(getClass().getResource("/TreasureMap.png"));
                foreground = new BufferedImage(background.getWidth(), background.getHeight(), BufferedImage.TYPE_INT_ARGB);
            } catch (Exception e) {
                e.printStackTrace();
            }

            MouseAdapter mouseHandler = new MouseAdapter() {
                private Point startPoint;

                @Override
                public void mousePressed(MouseEvent e) {
                    startPoint = e.getPoint();
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    startPoint = null;
                }

                @Override
                public void mouseDragged(MouseEvent e) {
                    Point endPoint = e.getPoint();
                    Graphics2D g2d = foreground.createGraphics();

                    Point offset = getOffset();

                    Point from = new Point(startPoint);
                    from.translate(-offset.x, -offset.y);
                    Point to = new Point(endPoint);
                    to.translate(-offset.x, -offset.y);
                    g2d.setColor(Color.RED);
                    g2d.setStroke(new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
                    g2d.draw(new Line2D.Float(from, to));
                    g2d.dispose();
                    startPoint = endPoint;
                    repaint();
                }
            };

            addMouseListener(mouseHandler);
            addMouseMotionListener(mouseHandler);

        }

        @Override
        public Dimension getPreferredSize() {
            return background == null ? super.getPreferredSize() : new Dimension(background.getWidth(), background.getHeight());
        }

        protected Point getOffset() {
            Point p = new Point();
            if (background != null) {
                p.x = (getWidth() - background.getWidth()) / 2;
                p.y = (getHeight() - background.getHeight()) / 2;
            }
            return p;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (background != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                Point offset = getOffset();

                g2d.drawImage(background, offset.x, offset.y, this);
                g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
                g2d.drawImage(foreground, offset.x, offset.y, this);
                g2d.dispose();
            }
        }
    }
}
于 2013-02-20T03:45:31.843 に答える