9

我正在使用 Java 的 Graphics2D 来生成图形的图形表示。我也在使用 ImageIO 来编写 PNG 文件。( ImageIO.write(image, "png", out);)

我想知道我应该如何编写 JUnit 测试来测试生成的图形是否符合预期。我可以预先生成 PNG 文件,但是如果字体在不同的机器上有点不同怎么办?

4

4 回答 4

2

对我来说,这个具体的实现似乎有效:

private void compareRasterImages(BufferedImage expectedPngIo, BufferedImage actualPngIo) throws AssertionError {
    int minX = expectedPngIo.getMinX();
    int minY = expectedPngIo.getMinY();
    int maxX = expectedPngIo.getMinX() + expectedPngIo.getWidth();
    int maxY = expectedPngIo.getMinY()+ expectedPngIo.getHeight();

    assertEquals(minX, actualPngIo.getMinX()); 
    assertEquals(minY, actualPngIo.getMinY()); 
    assertEquals(expectedPngIo.getHeight(), actualPngIo.getHeight()); 
    assertEquals(expectedPngIo.getWidth(), actualPngIo.getWidth()); 
    for (int x_i = minX; x_i < maxX; x_i++){
        for (int y_i = minY; y_i < maxY; y_i++) {
            assertEquals(expectedPngIo.getRGB(x_i, y_i), actualPngIo.getRGB(x_i, y_i));
        }
    }
}

我使用 ImageIO 从我的 PNG(作为字节 [])中检索 BufferedImage:

BufferedImage expectedPngIo = ImageIO.read(new ByteArrayInputStream(expectedPng));
enter code here
于 2014-06-23T10:58:25.643 回答
1

您可以尝试测试输出的特定已知功能,例如:

  • 在 (100,100) 处有一个白色像素吗?
  • 它的边框完全黑色?
  • 图像是预期的大小吗?

和/或您可以为某些“聚合属性”编写测试,从而使结果有些模糊:

  • 图像是否至少 90% 与参考图像匹配?(以允许不同的字体、抗锯齿差异等)
  • 图像中最常见的颜色是否等于背景颜色?
于 2010-08-03T21:08:19.770 回答
1

您可以将生成的图像的所有 RGB 值读入一个数组,并将该二维数组与表示预生成图像的数组进行比较,如果您确实对完整图像有特定的了解。

如果您希望忽略字体,您可以对不包含任何可变数据的图像区域执行相同操作,具体取决于生成图像的环境。为单元测试构建校正和规范化例程将是浪费时间,除非期望应用程序生成所需的高精度图像。

于 2010-08-03T21:21:41.767 回答
1

我发现这可以有效地使渲染的字体跨平台进行像素完美的图形单元测试,例如覆盖在静态图像上的文本。

  1. FontandFontRenderContext注入到渲染字体的类中,以便可以在测试中控制它们。
  2. 将 .ttf 文件提供给单元测试并用于Font.createFont()从文件生成字体。
  3. 在单元测试中,在使用中禁用抗锯齿FontRenderContext。如果你跳过这一步,结果看起来确实会因平台而异。

我很好奇其他人是否认为这很脆弱或容易失败,但到目前为止我已经取得了很好的结果。

于 2016-11-19T20:41:15.980 回答