将JUNG图写入图像:无法可靠地呈现完整的图形

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

谢谢!

public void writeImage(String filename) { Layout layout = new CircleLayout(jungGraph); layout.setSize(innerSize); bvs = new BasicVisualizationServer(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()); bvs.getRenderContext().setVertexLabelTransformer(new ToStringLabeller()); 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); } } 

我们通常希望保存被操纵图形的状态。 我们按照我们喜欢的方式缩放和定位组件,然后我们制作容器的照片。 这可以这样实现:

  1. 从优秀的Rob Camick博客获取ScreenImage类
  2. 将JSarollPane中的JPanel或承载JUNG2图形的任何Component传递给ScreenImage.createImage以创建图像。

     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. 另请阅读上述博客的其他主题:-)

您还可以使用VisualizationImageServer 。 它是BasicVisualizationServer的子类型,它添加了一个getImage方法。 我毫不费力地正确渲染图表。

那么你的代码就像:

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