Java Graphics.fillPolygon:如何渲染右边缘和下边缘?

2023-11-21

绘制多边形时,Java2D 会忽略右边缘和底边缘。我明白为什么要这样做。然而,我想画一些包含这些边缘的东西。我想到的一件事是遵循fillPolygon with drawPolygon具有相同的坐标,但这似乎留下了间隙。 (参见底部的小三角形图像。)有两种可能性,但我不知道是哪一种。为了启用抗锯齿功能,我这样做:

renderHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
                  RenderingHints.VALUE_ANTIALIAS_ON);
renderHints.put(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHints(renderHints);

一种可能性是 Alpha 通道上没有进行抗锯齿处理,因此间隙是由过度绘制造成的。在这种情况下,如果 Alpha 通道是被抗锯齿的通道,则边缘将正确邻接。另一种可能性是,这里只是有一个缺口。

我怎样才能解决这个问题?

另外,我不确定,但看来多边形轮廓实际上可能太大了。也就是说,它可能比我想要包含的右边缘和下边缘更远。

Thanks.

enter image description here

- 更新 -

基于 Hovercraft Full of Eels 的一个非常好的建议,我做了一个可编译的示例:

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

public class polygon {
   private static final int WIDTH = 20;

   public static void main(String[] args) {
      BufferedImage img = new BufferedImage(WIDTH, WIDTH, BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = img.createGraphics();
      int[] xPoints = {WIDTH / 3, (2*WIDTH) / 3, WIDTH / 3};
      int[] yPoints = {0, WIDTH / 2, WIDTH};
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setColor(Color.green);
      g2.drawLine(0, WIDTH-1, WIDTH, WIDTH-1);
      g2.drawLine(0, 0, WIDTH, 0);
      g2.drawLine(WIDTH/3, 0, WIDTH/3, WIDTH);
      g2.drawLine((2*WIDTH/3), 0, (2*WIDTH/3), WIDTH);
      g2.setColor(Color.black);
      g2.drawPolygon(xPoints, yPoints, xPoints.length);
      g2.setColor(Color.black);
      g2.fillPolygon(xPoints, yPoints, xPoints.length);
      g2.dispose();

      ImageIcon icon = new ImageIcon(img);
      JLabel label = new JLabel(icon);

      JOptionPane.showMessageDialog(null, label);
   }
}

如果将填充的多边形保留为红色,则会得到下图(缩放 500%),这表明多边形并未一直延伸到右边缘。也就是说,垂直的绿线对应于x=(2*WIDTH)/2,尽管红色多边形包含该坐标,但它不会在那里绘制任何像素。

enter image description here

为了看到差距问题,我改变了red在程序中black。在此图像中,您可以在右下角看到一个微妙的间隙,其中绘制的轮廓drawPolygon不太符合所画的内容fillPolygon.

enter image description here


在简单的可编译可运行程序中向我们展示您的绘图代码。例如,当我尝试模仿您的图像并使用 RenderingHints 时,它似乎会生成具有完整右/下边缘的适当大小的图像:

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class Foo002 {
   private static final int WIDTH = 20;

   public static void main(String[] args) {
      BufferedImage img = new BufferedImage(WIDTH, WIDTH,
            BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = img.createGraphics();
      int[] xPoints = { WIDTH / 3, (2 * WIDTH) / 3, WIDTH / 3 };
      int[] yPoints = { 0, WIDTH / 2, WIDTH };
      g2.setColor(Color.black);
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setRenderingHint(RenderingHints.KEY_RENDERING,
            RenderingHints.VALUE_RENDER_QUALITY);
      g2.fillPolygon(xPoints, yPoints, xPoints.length);
      g2.dispose();

      ImageIcon icon = new ImageIcon(img);
      JLabel label = new JLabel(icon);
      label.setBorder(BorderFactory.createLineBorder(Color.black));
      JPanel panel = new JPanel();
      panel.add(label);

      JOptionPane.showMessageDialog(null, panel);
   }
}

如果您可以向我们展示一个能够重现您的问题的类似程序,那么我们可以为您提供更好的帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java Graphics.fillPolygon:如何渲染右边缘和下边缘? 的相关文章

  • Java 字符串哈希码缓存

    字符串不变性的优点之一是哈希码缓存以实现更快的访问 在这种情况下 如何处理具有相同哈希码的字符串的缓存 在这种情况下它真的能提高性能吗 在这种情况下 如何处理具有相同哈希码的字符串的缓存 被缓存的是字符串的哈希码 它被缓存在私有的int字符
  • jvm中本机代码如何转换为机器代码[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我读过一些文章说 jvm将字节码转换为机器码 jvm将字节码转换为本机代码 jvm 将字节码转换为系统调用 系统调用又由操作系统与硬件
  • Java中的文字赋值[重复]

    这个问题在这里已经有答案了 定义上有什么区别 double example 23 1d or double example 23 1 为什么long float double可以以l f d结尾 之间没有区别double example 2
  • 使用正则表达式验证输入字符串是否为 0-255 之间的数字

    我在将输入字符串与正则表达式匹配时遇到问题 我想验证输入数字在 0 255 之间并且长度最多应为 3 个字符 代码工作正常 但当我输入 000000 至任意长度时 显示 true 而不是 false 这是我的代码 String IP 000
  • jpa2 CriteriaBuilder order by “ORDER BY 表达式必须出现在选择列表中”

    我正在写一个查询标准生成器 但无法添加order by子句 因为它随消息一起抛出错误ORDER BY 表达式必须出现在选择列表中这是我的实体 public class A Integer aId ManyToOne JoinColumn n
  • Glassfish:在部署期间修改 EAR 的部署描述符

    经过几天的搜索 尝试和摇头 我将这个问题发布到 SO 尽管它seems已经得到答复 这是场景 我有一个 EAR 应用程序 目前 包含一个 WAR 和一个 EJB 模块 EJB 模块使用 JPA persistence xml 并且一些无状态
  • 初始堆大小无效。无法创建Java虚拟机

    我遇到了下一个问题 我尝试通过startup bat手动启动Tomcat 但似乎没有显示任何结果 然后我尝试运行shutdown bat 控制台显示如下 D apache tomcat 7 0 35 bin gt startup bat U
  • 如何为java注释处理器编写自动化单元测试?

    我正在尝试使用 java 注释处理器 我可以使用 JavaCompiler 编写集成测试 事实上我现在正在使用 hickory 我可以运行编译过程并分析输出 问题 即使我的注释处理器中没有任何代码 单个测试也会运行大约半秒 对于以 TDD
  • 从字符串生成密钥?

    我需要从字符串生成一个密钥 以便我始终可以从同一字符串创建相同的密钥 具体来说是一个Key对象 这样我就可以用它来创建Cipher进而创建SealedObject 这在 Java 中可行吗 我应该考虑什么类 方法组合才能做到这一点 对于 A
  • EMF Eclipse:带有自定义字段(属性)的枚举

    好吧 在 Java 中这是可能的 import org eclipse emf common util Enumerator public enum MyEnum implements Enumerator LITERAL1 0 Name
  • bufferedinputstream 中标记读取限制有什么用

    我是Java流的新手 我想读取特定的文件内容 然后需要从头开始读取 我创建了一个 BufferedInputStream 但我对 BufferedInputStream mark int markLimit 的文档感到困惑 文档说 publ
  • “___ 中的方法 ___() 是在无法访问的类或接口中定义的”编译错误

    我发现了一个奇怪的编译限制 我无法解释 并且我不明白这个限制的原因 示例1 考虑这些类 In package e1 public class C1 enum E1 A B C public E1 x In package e2 import
  • Java 验证日期为 yyyyMMddHHmmss

    我想在java中验证给定的日期格式为yyyyMMddHHmmss 状况 应符合格式 yyyyMMddHHmmss 它应该验证当前日期 它应该验证与当前小时有 3 小时或 3 小时差异的小时数 如果满足所有三个条件 Java 方法应返回 tr
  • 在 REST Web 服务中接受逗号分隔值

    我正在尝试接收 REST URI 中以逗号分隔值形式的字符串列表 示例 http localhost 8080 com vogella jersey first rest todo test 1 abc test 其中 abc 和 test
  • 更新分页。是否可以?

    他们是否存在一些方法来处理更新分页 例如我有 100 行类型 Id private Integer id Column private boolean flag Column private Date last 一开始它们看起来像 id f
  • 如何在速度模板中检索哈希图值

    如何从速度模板中的以下哈希图中检索值 请帮忙 LinkedHashMap
  • Spring Transactional 减慢了整个过程

    我正在尝试分析我有两堂课的情况 其中一个类是 ProcessImpl 它是起点并在内部调用其他子事务 我不知道出了什么问题 processImpl正在导入一些东西并将相关数据写入数据库 Specs Spring orm版本 3 2 18 发
  • AndroidAnnotations 和 Dagger

    我正在尝试使用 Dagger 注入 Android 带注释的 Activity java lang IllegalArgumentException No inject registered for members com app serv
  • 获取Java中ResultSet返回的行数

    我用过一个ResultSet返回一定数量的行 我的代码是这样的 ResultSet res getData if res next System out println No Data Found while res next code t
  • Java 可变 BigInteger 类

    我正在使用 BigIntegers 进行计算 该计算使用一个调用 multiply 大约 1000 亿次的循环 并且从 BigInteger 创建新对象使其非常慢 我希望有人编写或找到了 MutableBigInteger 类 我在 jav

随机推荐