将 JUNG 图写入图像:无法可靠地渲染完整的图

发布于 2024-10-19 14:56:52 字数 2042 浏览 1 评论 0原文

我一直在使用 JUNG 来可视化一些简单的图表,我想将其中的几个写入 PNG 文件。不幸的是,图像通常看起来是在图形完成绘制之前渲染的,这意味着我得到的图形不完整——也就是说,只有一半的边或节点被绘制的图形——大约有一半的时间。渲染到屏幕效果很好,这就是我如此困惑的部分原因。正如您将在下面看到的,我尝试了几种解决方法,但它们没有帮助。知道我正在使用的 basicVisualizationServer 不会直接绘制任何对 BufferedImage 有用的东西可能很有用——当我尝试这样做时,我只是得到一个黑色图像。

谢谢!

  public void writeImage(String filename) {
    Layout layout = new CircleLayout<V, E>(jungGraph);
    layout.setSize(innerSize);
    bvs = new BasicVisualizationServer<V,E>(layout);
    float strokeWidth = 8f;
    bvs.getRenderContext().setVertexShapeTransformer(new ConstantTransformer(new Ellipse2D.Float(-24,-24,48,48)));
    bvs.getRenderContext().setArrowDrawPaintTransformer(new ConstantTransformer(Color.black));
    bvs.getRenderContext().setEdgeStrokeTransformer(new ConstantTransformer(new BasicStroke(strokeWidth)));
    bvs.getRenderContext().setEdgeArrowStrokeTransformer(new ConstantTransformer(new BasicStroke(strokeWidth)));
    bvs.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller<E>());
    bvs.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<V>());
    bvs.setPreferredSize(viewSize);
    //int width = bvs.getWidth(); // Always returns zero
    int width = viewFrame.getWidth();
    //int height = bvs.getHeight(); // Always returns zero
    int height = viewFrame.getHeight();

    BufferedImage bim = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g = bim.createGraphics();
    viewFrame.paintAll(g);

    g.dispose();
    //this.viewFrame.paintComponents(g);
    //try{Thread.sleep(1000);} catch(Exception e) {throw new RuntimeException(e);} // Sleeping doesn't help.
    try {
        File f = new File(filename);
        ImageIO.write(bim,"png",f);
        System.out.println("wrote image for " + jungGraph + " to "+ filename+ ":" + f.toString());
        //try{Thread.sleep(500);} catch(Exception e) {throw new RuntimeException(e);} // Doesn't help
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

I've been using JUNG to visualize some simple graphs, and I'd like to write several of them to a PNG file. Unfortunately, the images often appear to render before the graph is finished painting, meaning that I get incomplete graphs -- that is, graphs where only a hanfdul of edges or nodes are drawn -- about half of the time. Rendering to screen works fine, which is part of why I'm so puzzled. As you'll see below, I tried a couple of workarounds, but they didn't help. It may be useful to know that the basicVisualizationServer I'm using won't paint anything useful to the BufferedImage directly -- I just get a black image when I try that.

Thanks!

  public void writeImage(String filename) {
    Layout layout = new CircleLayout<V, E>(jungGraph);
    layout.setSize(innerSize);
    bvs = new BasicVisualizationServer<V,E>(layout);
    float strokeWidth = 8f;
    bvs.getRenderContext().setVertexShapeTransformer(new ConstantTransformer(new Ellipse2D.Float(-24,-24,48,48)));
    bvs.getRenderContext().setArrowDrawPaintTransformer(new ConstantTransformer(Color.black));
    bvs.getRenderContext().setEdgeStrokeTransformer(new ConstantTransformer(new BasicStroke(strokeWidth)));
    bvs.getRenderContext().setEdgeArrowStrokeTransformer(new ConstantTransformer(new BasicStroke(strokeWidth)));
    bvs.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller<E>());
    bvs.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<V>());
    bvs.setPreferredSize(viewSize);
    //int width = bvs.getWidth(); // Always returns zero
    int width = viewFrame.getWidth();
    //int height = bvs.getHeight(); // Always returns zero
    int height = viewFrame.getHeight();

    BufferedImage bim = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g = bim.createGraphics();
    viewFrame.paintAll(g);

    g.dispose();
    //this.viewFrame.paintComponents(g);
    //try{Thread.sleep(1000);} catch(Exception e) {throw new RuntimeException(e);} // Sleeping doesn't help.
    try {
        File f = new File(filename);
        ImageIO.write(bim,"png",f);
        System.out.println("wrote image for " + jungGraph + " to "+ filename+ ":" + f.toString());
        //try{Thread.sleep(500);} catch(Exception e) {throw new RuntimeException(e);} // Doesn't help
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你与昨日 2024-10-26 14:56:52

您还可以使用VisualizationImageServer。它是 BasicVisualizationServer 的子类型,添加了 getImage 方法。我在正确渲染图表方面没有遇到任何问题。

那么你的代码将是这样的:

public void writeImage(String filename) {
    Layout layout = new CircleLayout<V, E>(jungGraph);
    layout.setSize(innerSize);
    bvs = new VisualizationImageServer<V,E>(layout);
    // [...]
    BufferedImage image = (BufferedImage)bvs.getImage();
}

You can also use VisualizationImageServer. It's a subtype of BasicVisualizationServer which adds a getImage method. I have had no trouble with it rendering the graphs properly.

Your code would then be like:

public void writeImage(String filename) {
    Layout layout = new CircleLayout<V, E>(jungGraph);
    layout.setSize(innerSize);
    bvs = new VisualizationImageServer<V,E>(layout);
    // [...]
    BufferedImage image = (BufferedImage)bvs.getImage();
}
吹梦到西洲 2024-10-26 14:56:52

我们通常想要保存操作图的状态。我们按照自己喜欢的方式缩放和定位组件,然后制作容器的图片。这可以通过以下方式实现:

  1. 从优秀的 Rob Camick 的博客<获取 ScreenImage 类< /a>
  2. 将 JScrollPane 内的 JPanel 或托管 JUNG2 图形的任何组件传递到 ScreenImage.createImage 以创建图像。

    private void writeToImageFile(String imageFileName) {
    
       BufferedImage bufImage = ScreenImage.createImage((JComponent) jPanel1);
       尝试 {
           文件outFile = new File(imageFileName);
           ImageIO.write(bufImage, "png", outFile);
           System.out.println("将图像写入" + imageFileName);
       } catch (异常 e) {
           System.out.println("writeToImageFile(): " + e.getMessage());
       }
    }
    
  3. 另请阅读上述博客的其他主题:-)

We usually want to save the state of a manipulated graph. We zoom and position the components the way we like and then we make a picture of the container. This can be achieved like this:

  1. Get the ScreenImage Class from the excellent Rob Camick's blog
  2. Pass the JPanel inside your JScrollPane, or any Component that hosts your JUNG2 graph to ScreenImage.createImage in order to create an image.

    private void writeToImageFile(String imageFileName) {
    
       BufferedImage bufImage = ScreenImage.createImage((JComponent) jPanel1);
       try {
           File outFile = new File(imageFileName);
           ImageIO.write(bufImage, "png", outFile);
           System.out.println("wrote image to " + imageFileName);
       } catch (Exception e) {
           System.out.println("writeToImageFile(): " + e.getMessage());
       }
    }
    
  3. Read also other topics of the above mentioned blog :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文