【问题标题】:SVG Circle Resolution in JavaJava中的SVG圆分辨率
【发布时间】:2013-12-22 05:52:41
【问题描述】:

我有一个用 SVG 表示的圆圈:

    <circle cx="50" cy="50" r="50" stroke="black" stroke-width="1" style="fill:white"/>

然后我将此圆转换为 Java 中的 BufferedImage,宽度和高度 = 100,imageType = BufferedImage.TYPE_INT_ARGB。然后我通过以下代码将此 BufferedImage 绘制到另一个上:

    BufferedImage source = ImageIO.read(new File("imgToDrawOnto.png"));
    Graphics g = source.getGraphics();
    g.drawImage(circleImg, 100, 100, null);

其中 circleImg 是 SVG 圆的 BufferedImage。这可以正常工作并绘制到图像上,但是它非常像素化。有什么办法可以让圆更平滑吗?我宁愿继续使用 SVG,但如果 SVG 没有办法,也可以考虑其他方式。

我尝试过的事情:

  1. 我已将圆的半径设置为 500,并将 BufferedImage 的高度和宽度设置为 100。
  2. 我已将 BufferedImage 的高度和宽度设置为 1000,并使用 draw 方法将高度和宽度作为参数并将它们设置为 100。
  3. 我同时完成了 1 和 2。
  4. 我也尝试过使半径更大,即。 2500
  5. 我还将 circleImg 参数更改为 circleImg.getScaledInstance(100, 100, 1)

没有任何效果。有些看起来更平滑,但不是很多,有些看起来更糟。另外需要注意的是,我在使用 g.drawOval(150, 150, 100, 100) 时也观察到像素化。这让我相信问题不在于 SVG,但我可能错了。

Java 版本:

java版本“1.6.0_30” Java SE 运行时环境(内部版本 1.6.0_30-b12) Java HotSpot 64 位服务器 VM(内部版本 20.5-b03,混合模式)

对于 SVG,我使用的是 SVG-Salamander v1.0

【问题讨论】:

    标签: java svg svg-salamander


    【解决方案1】:

    当您使用ImageIO.read 读取图像时,图像文件的颜色模型将被保留。由于您阅读的是 PNG 文件,因此问题可能是源文件使用的索引颜色模型(调色板)很少,甚至可能不匹配颜色。另一个问题可能是您必须启用抗锯齿以避免所谓的像素化。

    为避免颜色模型问题,您可能需要创建一个新的 BufferedImage,例如ARGB 颜色模型,您首先在其上绘制加载的图像,然后绘制 SVG 图形:

    BufferedImage source = ImageIO.read(new File("imgToDrawOnto.png"));
    BufferedImage newImage = new BufferedImage(
        source.getWidth(), 
        source.getHeight(), 
        BufferedImage.TYPE_INT_ARGB);
    
    Graphics2D g = (Graphics2D)newImage.getGraphics();
    
    g.drawImage(source, 0, 0, null);
    g.drawImage(circleImg, 100, 100, null);
    

    要启用抗锯齿,您可以在绘制其他图像之前在Graphics2D 对象上设置适当的渲染提示:

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

    您还可以选择通过启用双线性或双三次插值来提高抗锯齿质量:

    g.setRenderingHint(
        RenderingHints.KEY_INTERPOLATION,
        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    
    g.setRenderingHint(
        RenderingHints.KEY_INTERPOLATION,
        RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    

    添加示例图片:

    【讨论】:

    • 尝试将源图像绘制到新的缓冲图像上,没有用。尝试使用两种插值类型进行抗锯齿,没有用。还同时尝试了两种建议,仍然没有成功。
    • 在这种情况下,您可能必须更清楚自己实际在做什么。发布一个完整的示例来重现您的行为并清楚地说明您的实际期望。
    • 很遗憾,我无法发布完整的代码示例,因为我的公司不允许这样做,但是如果您将我发布的 3 行中的 g.drawImage 替换为 g.drawOval,您将看到相同的像素化。我想要的只是让圆圈更平滑。
    • 由于我没有您正在阅读的PNG文件,因此我当然无法运行您发布的代码,即使我替换了最后一行。使用我在图像中发布结果的建议在 BufferedImage 中绘制一个圆圈,我将其添加到我的答案中,并且可用分辨率无法获得更好的结果。
    • 感谢您的帮助,原来我只是个白痴。圆圈被绘制到它自己的缓冲图像上,我没有在该图形对象上设置抗锯齿和插值。完成并且现在可以工作了。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 2015-05-18
    • 2021-09-24
    • 1970-01-01
    • 2019-10-14
    • 2017-10-02
    • 2017-03-09
    相关资源
    最近更新 更多