【问题标题】:Clipping is jagged despite anti-aliasing尽管有抗锯齿,但剪辑是锯齿状的
【发布时间】:2018-02-18 06:47:27
【问题描述】:

我正在尝试使用RoundRectangle2D.Double 剪裁我的Graphics2D 画布,但剪裁非常锯齿且不平滑。我有以下抗锯齿代码:

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

我知道它有效,因为当我使用 Graphics2D.fill() 绘制 RoundRectangle2D.Double 时,平滑效果很好。如何使剪辑平滑?

注意:我知道this post,但这与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();
    }
}

【问题讨论】:

  • 您使用的术语是“软剪辑”,setClip 不提供抗锯齿支持,这通常是我不使用的原因,而是倾向于使用遮罩技术,虽然更复杂,它们允许软剪辑。 For exampleexampleexample
  • “但这与 JPanel 和图像有关,但我不处理其中任何一个” - 那么您从哪里获得 Graphics 上下文?
  • @MadProgrammer 我看了这些例子,但我仍然不确定如何应用它们。我的意思是我不是在处理JPanelsImages,因为我不想剪辑或更改面板或图像的形状。我使用的唯一面板是占用JFrame 的空间以便我绘制的单个面板。所以我不明白我将如何使用遮罩(据我了解是通过改变JPanels 的形状以及在它们周围绘图来实现的?)仅在Graphics 上下文中我没有使用任何额外的@987654340 @ 或 Images 来自。
  • 这就是问题所在,这个问题缺乏上下文,我们无法从你的问题中推测你是如何获取信息的,你是如何操纵的。我现在提供了不少于 4 个可运行的示例,这些示例演示了可以解决核心问题的“软剪辑”方法。现在的问题是,您需要弄清楚如何最好地将这些想法融入您的问题中-您问题的基本答案是“使用软剪辑方法”-除此之外,我们不可能为您提供任何额外的支持

标签: java graphics graphics2d clip


【解决方案1】:

因此,根据您的示例,“简单”的答案是作弊。

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 形状填充它。

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

您“可能”解决问题的方法有多种,使用中间 BufferedImages 是一种(因此您可以将内容限制到指定区域,但仍应用“软剪辑”),但对于这种情况,这将是您可用的最简单的解决方案

【讨论】:

  • 这不会在拐角处造成问题吗?会画出少量应该被剪裁的东西。
  • @soggytoast 这将取决于您的要求,如果您很聪明,您将在圆边的范围内进行渲染(或者至少我会)。正如我所说,另一种选择是使用另一个BufferedImage,它将充当您将剪辑的主要渲染表面,然后您将在其后面绘制背景(正如我在问题中所讨论的那样),或者复合多个缓冲图像或简单地在paintComponent 方法中使用filldrawImage 的组合
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-18
  • 1970-01-01
  • 2013-01-02
  • 2016-06-28
  • 2011-07-05
  • 2014-03-19
相关资源
最近更新 更多