如何在 JavaFX 2.2 中绘制清晰、不透明的发际线? [英] How to draw a crisp, opaque hairline in JavaFX 2.2?

查看:19
本文介绍了如何在 JavaFX 2.2 中绘制清晰、不透明的发际线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 JavaFX 2.2 中绘制清晰、不透明的细线的最佳方法是什么?

What is the best way to draw a crisp, opaque hairline in JavaFX 2.2?

文档说,如果 strokeWidth0.0d,它将是一条细线,但它根本不可见.值 <代码>>0.0d 和 <1.0d 显示的线条非常好,但也不显示不透明的行为.当一条线切割另一条线时,相交点比线的其余部分更亮(我希望这种行为来自具有一定透明度的线).最后,1.0d 绘制了一条宽度为几个像素的白线.

The documentation says, that with a strokeWidth of 0.0d it'll be a hairline, but it's just not visible at all. Values > 0.0d and <1.0d show lines that are pretty fine, but also don't show an opaque behaviour. When one line cuts another, the intersecting points are lighter than the rest of the line (i'd expect this behaviour from a line with some transparency). Finally, 1.0d draws a white line with several pixels width.

这是我的测试代码:

LineBuilder.create().startX(i*gridSize).startY(0).endX(i*gridSize).endY(height).smooth(false).stroke(Color.WHITE).strokeWidth(0.5d).fill(Color.WHITE).build();           

推荐答案

您可以使用 Region 子类,例如 窗格,用于您的父级,带有 snapToPixel 设置为 true.

You can use a Region subclass, such as a Pane for your Parent, with snapToPixel set to true.

此外,请参阅Node 文档在坐标系上.

Additionally, refer to the Node documentation on the co-ordinate system.

在设备像素级别,整数坐标映射到角落并且像素和像素中心之间的裂缝出现在整数像素位置之间的中点.因为都是坐标值用浮点数指定,坐标可以精确地指向这些角(当浮点值有精确的整数值)或像素上的任何位置.例如,一个(0.5, 0.5) 的坐标将指向左上角的中心舞台上的像素.类似地,在 (0, 0) 处的矩形尺寸为10 x 10 将从左上角的左上角跨越舞台上第 10 个像素右下角的像素第 10 条扫描线.里面最后一个像素的像素中心矩形将在坐标 (9.5, 9.5) 处.

At the device pixel level, integer coordinates map onto the corners and cracks between the pixels and the centers of the pixels appear at the midpoints between integer pixel locations. Because all coordinate values are specified with floating point numbers, coordinates can precisely point to these corners (when the floating point values have exact integer values) or to any location on the pixel. For example, a coordinate of (0.5, 0.5) would point to the center of the upper left pixel on the Stage. Similarly, a rectangle at (0, 0) with dimensions of 10 by 10 would span from the upper left corner of the upper left pixel on the Stage to the lower right corner of the 10th pixel on the 10th scanline. The pixel center of the last pixel inside that rectangle would be at the coordinates (9.5, 9.5).

另请参阅 Shape 文档:

大多数节点倾向于只对它们应用整数转换,并且通常它们也使用整数坐标定义.为了在这种常见情况下,具有直线边缘的形状的填充往往是清晰,因为它们与落在的像素之间的裂缝对齐整数设备坐标,因此倾向于自然地覆盖整个像素.另一方面,抚摸这些相同的形状通常会导致模糊轮廓,因为默认的描边属性同时指定默认笔画宽度是 1.0 坐标,通常映射到正好 1 个设备像素,并且笔画应该跨越形状的边框,在边框的两侧下降一半.自从许多常见形状的边界往往直接落在整数上坐标和那些整数坐标通常精确映射到整数设备位置,边界往往会导致 50% 的覆盖率在边框两侧的像素行和列上形状而不是 100% 覆盖一个或另一个.因此,填充可能通常是清脆的,但笔画通常是模糊的.

Most nodes tend to have only integer translations applied to them and quite often they are defined using integer coordinates as well. For this common case, fills of shapes with straight line edges tend to be crisp since they line up with the cracks between pixels that fall on integer device coordinates and thus tend to naturally cover entire pixels. On the other hand, stroking those same shapes can often lead to fuzzy outlines because the default stroking attributes specify both that the default stroke width is 1.0 coordinates which often maps to exactly 1 device pixel and also that the stroke should straddle the border of the shape, falling half on either side of the border. Since the borders in many common shapes tend to fall directly on integer coordinates and those integer coordinates often map precisely to integer device locations, the borders tend to result in 50% coverage over the pixel rows and columns on either side of the border of the shape rather than 100% coverage on one or the other. Thus, fills may typically be crisp, but strokes are often fuzzy.

避免这些模糊轮廓的两种常见解决方案是使用更广泛的完全覆盖更多像素的笔画 - 通常是笔画宽度如果没有有效的比例变换,2.0 将实现这一点 -或指定 StrokeType.INSIDE 或 StrokeType.OUTSIDE笔画样式 - 将默认的单个单位笔画偏向全像素行或列之一就在其内部或外部形状的边框.

Two common solutions to avoid these fuzzy outlines are to use wider strokes that cover more pixels completely - typically a stroke width of 2.0 will achieve this if there are no scale transforms in effect - or to specify either the StrokeType.INSIDE or StrokeType.OUTSIDE stroke styles - which will bias the default single unit stroke onto one of the full pixel rows or columns just inside or outside the border of the shape.

因此,如果您将节点留在不 snapToPixel 的组或区域中,您可以按照 Shape 文档中的上述说明进行操作.

So, if you leave your Nodes in a Group or Region which does not snapToPixel, you can follow the above instructions from the Shape documentation.

这是一些示例代码:

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.LineBuilder;
import javafx.scene.shape.StrokeType;
import javafx.scene.text.Text;
import javafx.stage.Stage;

/** http://stackoverflow.com/questions/11886230/how-to-draw-a-crisp-opaque-hairline-in-javafx-2-2 */
public class LineWidths extends Application {
  public static void main(String[] args) { launch(args); }

  @Override public void start(Stage stage) {
    Line fuzzyline = LineBuilder.create()
        .startX(5).startY(50)
        .endX(90).endY(50)
        .stroke(Color.BLACK).strokeWidth(1)
      .build();
    Line hairline = LineBuilder.create()
        .startX(4.5).startY(99.5)
        .endX(89.5).endY(99.5)
        .stroke(Color.BLACK).strokeWidth(1)
      .build();
    Line fatline = LineBuilder.create()
        .startX(5).startY(150)
        .endX(90).endY(150)
        .stroke(Color.BLACK).strokeWidth(1).strokeType(StrokeType.OUTSIDE)
      .build();
    Pane snappedPane = new Pane();
    Line insideline = LineBuilder.create()
        .startX(5).startY(25)
        .endX(90).endY(25)
        .stroke(Color.BLACK).strokeWidth(1)
      .build();
    snappedPane.setSnapToPixel(true);
    snappedPane.getChildren().add(insideline);
    snappedPane.setPrefSize(100, 50);
    snappedPane.relocate(-0.5, 174.5);

    stage.setScene(
      new Scene(
        new Group(
          fuzzyline, hairline, fatline, snappedPane,
          new Text(10, 40, "fuzzyline"),  
          new Text(10, 90, "hairline"),  
          new Text(10, 140, "fatline"),  
          new Text(10, 190, "snappedPane")
        ), 100, 250
      )
    );
    stage.show();
  }
}

这篇关于如何在 JavaFX 2.2 中绘制清晰、不透明的发际线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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