剪辑是锯齿状的尽管抗锯齿

问题描述 投票:0回答:2

我正在尝试使用

Graphics2D
剪裁我的
RoundRectangle2D.Double
画布,但剪裁非常参差不齐且不平滑。我有以下代码来消除锯齿:

Graphics2D g = (Graphics2D)graphics;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

我知道它有效,因为当我使用

RoundRectangle2D.Double
绘制
Graphics2D.fill()
时,平滑效果很好。如何使剪裁平滑?

注意:我知道这篇文章,但这与

JPanels
和图像有关,但我不处理其中任何一个。我只是想平滑地剪切绘图区域的一部分。

在此先感谢您的帮助。

Example.java

import java.awt.*;
import java.awt.geom.RoundRectangle2D;

import javax.swing.*;

public class Example extends JPanel {
    public Example() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.setLocation(10, 10);
        setPreferredSize(new Dimension(400, 400));
        setBackground(Color.BLACK);
        Container container = frame.getContentPane();
        container.add(this);
        frame.pack();
        frame.setVisible(true);
    }

    public void paintComponent(Graphics graphics) {
        super.paintComponent(graphics);
        Graphics2D g = (Graphics2D)graphics;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        RoundRectangle2D clippingArea = new RoundRectangle2D.Double(50, 50, getWidth() - 100, getHeight() -100, 40, 40);
        g.setClip(clippingArea);

        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.BLACK);
        String s = "area for me to draw on where";
        g.drawString(s, getWidth()/2 - g.getFontMetrics().stringWidth(s)/2, getHeight()/2 - g.getFontMetrics().getHeight());
        s = "the roundrectangle should be anti-aliased";
        g.drawString(s, getWidth()/2 - g.getFontMetrics().stringWidth(s)/2, getHeight()/2);
    }

    public static void main(String[] args) {
        new Example();
    }
}
java graphics graphics2d clip
2个回答
0
投票

所以,根据你的例子,“简单”的答案是作弊。

RoundRectangle2D clippingArea = new RoundRectangle2D.Double(50, 50, getWidth() - 100, getHeight() - 100, 40, 40);
// Make the clipping space rectangular
g.setClip(clippingArea.getBounds2D());

g.setColor(Color.WHITE);
g.fill(clippingArea);
g.setColor(Color.BLACK);

基本上所有这一切都使裁剪区域成为矩形,然后使用

RoundRectangle2D
形状填充它。

因为你的大部分问题都围绕边缘展开,这消除了核心问题,圆边。

您“可能”解决问题的方法有多种,使用中间

BufferedImage
s 是一种方法(因此您可以将内容限制在指定区域,但仍应用“软裁剪”),但对于这种情况,这将是最简单的解决方案


0
投票

你提的问题有两种思路

第一个想法
使用 setClip() 方法设置剪辑,并使用 Graphics 类的方法在特定范围内绘制。 这也是你提出来的idea

第二个想法
创建一个具有 Graphics 类型的 graphicsObj 字段的 BufferedImage 对象。 为图形对象设置渲染提示,如下所示:

graphicsObj.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

使用 fillOval() 方法绘制一个椭圆。 然后,使用 setComposite() 方法,为 Graphics 对象设置一个 AlphaComponent 对象,如下所示:

AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_IN);
graphicsObj.setComposite(alphaComposite);

然后使用 drawImage 或任何其他方法绘制一些东西。 这个 BufferedImage 就是你想要的。 只是不要忘记在任何要绘制 BufferedImage 的地方使用以下渲染提示:

setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

例子:

public void paint(Graphics g) {
            super.paint(g);

            BufferedImage bufferedImage = new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB);

            Graphics2D bg2 = bufferedImage.createGraphics();

            bg2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            bg2.fillOval(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());

            AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_IN);
            bg2.setComposite(alphaComposite);

            Image img = null;
            
            try {
                img = ImageIO.read(new File("some-image.png"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            if (img == null) {
                // TODO something
            } else {
                bg2.drawImage(img, 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), null);
            }

            Graphics2D g2 = (Graphics2D) g;
            
            g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

                g2.drawImage(bufferedImage, 0, 0, getWidth(), getHeight(), null);
        }
    }

第二个idea结果: The second idea result

© www.soinside.com 2019 - 2024. All rights reserved.