prevent画了一个Graphics2D的同一区域 [英] Prevent drawing over the same area of a Graphics2D

查看:402
本文介绍了prevent画了一个Graphics2D的同一区域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

语言:Java的

您好,我需要prevent画了一个Graphics2D的同一位置不止一次。例如,如果用户绘制使用具有圆帽和10在一定面积的宽度的的BasicStroke,同样的区域不能在第二时间绘制。

我想这样做的原因是,使得用户可以绘制(自由手)在图像半透明颜色,而不在同一行程绘图(从而增加了色彩的密度和减少其半透明)。

我试图存储由用户作出的所有笔划的形状(作为相减的形状区域的对象),然后通过所有这些区域的对象的相交削波的Graphics2D

这几乎工作,但通过剪辑获得的'形'是不太一样的笔画绘制的形状 - 这是出于一对夫妇像素

有没有人有可能工作的任何其他的想法?


解决方案

这个概念比较简单,你需要有在其上可以呈现...多层

有多种不同的方式来解决这个问题。你可以保持的S和每个油漆周期列表,使用<$ C $使这些点到后台缓冲区,你会再画过的主要内容C>的AlphaComposite 。

您可以(如本例一样)直接绘制到后备缓冲器和重绘的内容,再次使用的AlphaComposite 呈现更高的层。

您可以具有任何数目的层...

 进口java.awt.AlphaComposite中;
进口java.awt.BasicStroke中;
进口java.awt.Color中;
进口java.awt.Dimension中;
进口java.awt.EventQueue中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;
进口java.awt.Point中;
进口java.awt.event.MouseAdapter;
进口java.awt.event.MouseEvent中;
进口java.awt.geom.Line2D中;
进口java.awt.image.BufferedImage中;
进口javax.imageio.ImageIO中;
进口javax.swing.JFrame中;
进口javax.swing.JPanel中;
进口javax.swing.UIManager中;公共类PaintOver {    公共静态无效的主要(字串[] args){
        新PaintOver();
    }    公共PaintOver(){
        EventQueue.invokeLater(新的Runnable(){
            @覆盖
            公共无效的run(){
                尝试{
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                }赶上(例外前){
                }                JFrame的帧=新的JFrame(测试);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(新MapPane());
                frame.pack();
                frame.setLocationRelativeTo(NULL);
                frame.setVisible(真);            }
        });
    }    公共类MapPane继承JPanel {        私人的BufferedImage背景;
        私人的BufferedImage前景;        公共MapPane(){
            尝试{
                背景= ImageIO.read(的getClass()的getResource(/ TreasureMap.png));
                前景=新的BufferedImage(background.getWidth(),background.getHeight(),BufferedImage.TYPE_INT_ARGB);
            }赶上(例外五){
                e.printStackTrace();
            }            MouseAdapter mouseHandler =新MouseAdapter(){
                私人点的startPoint;                @覆盖
                公共无效鼠标pressed(的MouseEvent E){
                    的startPoint = e.getPoint();
                }                @覆盖
                公共无效的mouseReleased(的MouseEvent E){
                    的startPoint = NULL;
                }                @覆盖
                公共无效的mouseDragged(的MouseEvent E){
                    Point端点= e.getPoint();
                    Graphics2D的G2D = foreground.createGraphics();                    点偏移=的getOffset();                    从=新的点(的startPoint)点;
                    from.translate(-offset.x,-offset.y);
                    点=新的点(终点);
                    to.translate(-offset.x,-offset.y);
                    g2d.setColor(Color.RED);
                    g2d.setStroke(的新BasicStroke(4,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
                    g2d.draw(新Line2D.Float(从,到));
                    g2d.dispose();
                    的startPoint =端点;
                    重绘();
                }
            };            addMouseListener将(mouseHandler);
            addMouseMotionListener(mouseHandler);        }        @覆盖
        公共尺寸的get preferredSize(){
            返回后台== NULL? super.get preferredSize():新的Dimension(background.getWidth(),background.getHeight());
        }        保护点的getOffset(){
            点P =新的点();
            如果(背景!= NULL){
                p.x =(的getWidth() - background.getWidth())/ 2;
                p.y =(的getHeight() - background.getHeight())/ 2;
            }
            回磷;
        }        @覆盖
        保护无效paintComponent(图形G){
            super.paintComponent方法(G);
            如果(背景!= NULL){
                Graphics2D的G2D =(Graphics2D的)g.create();
                点偏移=的getOffset();                g2d.drawImage(背景,offset.x,offset.y,本);
                g2d.setComposite(AlphaComposite.SrcOver.derive(0.5F));
                g2d.drawImage(前景,offset.x,offset.y,这一点);
                g2d.dispose();
            }
        }
    }
}

Language: Java.

Hi, I need to prevent drawing over the same location of a Graphics2D more than once. For example, if the user draws using a BasicStroke with a round cap and a width of 10 over a certain area, that same area cannot be drawn on a second time.

The reason I want to do this is so that the user can draw (free-hand) translucent colours over an image without drawing over the same stroke (thus increasing the density of the colour and reducing its translucency).

I've tried storing the shapes of all the strokes made by the user (as Area objects that subtract the shape) and then clipping the Graphics2D by the intersection of all those Area objects.

This almost works, but the 'shape' obtained by the clip is not quite the same as the 'shape' drawn by the stroke - it is out by a couple of pixels.

Does anyone have any other ideas that might work?

解决方案

The concept is relatively simple, you need to have multiple layers onto which you can render...

There are multiple different ways to approach the problem. You could maintain a list of Points and on each paint cycle, render these points to a backing buffer, which you would then draw over the main content using a AlphaComposite.

You could (as this example does) draw directly to the backing buffer and repaint the content, again, using a AlphaComposite to render the higher layer.

You could have any number of layers...

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

这篇关于prevent画了一个Graphics2D的同一区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆