Java 将容格图写入图像:can';不能可靠地绘制完整图

Java 将容格图写入图像:can';不能可靠地绘制完整图,java,image,jung,Java,Image,Jung,我一直在使用JUNG来可视化一些简单的图形,我想将其中的一些图形写入PNG文件。不幸的是,图像通常在图形完成绘制之前呈现,这意味着我会得到不完整的图形——也就是说,只绘制了一组边或节点的图形——大约有一半的时间。渲染到屏幕效果很好,这也是我如此困惑的部分原因。正如你在下面看到的,我尝试了一些变通方法,但都没有用。知道我正在使用的basicVisualizationServer不会直接为BuffereImage绘制任何有用的内容可能会很有用——我尝试这样做时只会得到一个黑色图像 谢谢 publ

我一直在使用JUNG来可视化一些简单的图形,我想将其中的一些图形写入PNG文件。不幸的是,图像通常在图形完成绘制之前呈现,这意味着我会得到不完整的图形——也就是说,只绘制了一组边或节点的图形——大约有一半的时间。渲染到屏幕效果很好,这也是我如此困惑的部分原因。正如你在下面看到的,我尝试了一些变通方法,但都没有用。知道我正在使用的basicVisualizationServer不会直接为BuffereImage绘制任何有用的内容可能会很有用——我尝试这样做时只会得到一个黑色图像

谢谢

  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);
    }
}
public void writeImage(字符串文件名){
布局=新的圆形布局(图);
布局。设置尺寸(内部尺寸);
bvs=新的基本可视化服务器(布局);
浮动冲程宽度=8f;
setVertexShapeTransformer(新ConstantTransformer(新的Ellipse2D.Float(-24,-24,48,48));
getRenderContext().setArrowDrawPaintTransformer(新ConstantTransformer(Color.black));
getRenderContext().SetEdgeStokeTransformer(新ConstantTransformer(新基本行程(行程宽度)));
getRenderContext().SetEdgerRowstroketTransformer(新ConstantTransformer(新基本行程(行程宽度)));
getRenderContext().setEdgeLabelTransformer(新的ToStringLabeller());
getRenderContext().setVertexLabelTransformer(新ToStringLabeler());
bvs.setPreferredSize(视图大小);
//int width=bvs.getWidth();//始终返回零
int width=viewFrame.getWidth();
//int height=bvs.getHeight();//始终返回零
int height=viewFrame.getHeight();
BuffereImage bim=新的BuffereImage(宽度、高度、BuffereImage.TYPE_INT_RGB);
Graphics2D g=bim.createGraphics();
视框.画框(g);
g、 处置();
//此.viewFrame.paintComponents(g);
//尝试{Thread.sleep(1000);}catch(异常e){throw new RuntimeException(e);}//睡眠没有帮助。
试一试{
文件f=新文件(文件名);
图像IO.write(bim,“png”,f);
System.out.println(“将“+jungGraph+”的图像写入“+filename+”:“+f.toString());
//试试{Thread.sleep(500);}catch(Exception e){throw new RuntimeException(e);}//没有帮助
}捕获(例外e){
抛出新的运行时异常(e);
}
}

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

  • 从优秀的网站上获取ScreenImage类
  • 将JScrollPane内的JPanel或承载JUNG2图形的任何组件传递到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());
       }
    }
    
  • 阅读上述博客的其他主题:-)

  • 您也可以使用。它是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();
    }
    
    public void writeImage(字符串文件名){
    布局=新的圆形布局(图);
    布局。设置尺寸(内部尺寸);
    bvs=新VisualizationImageServer(布局);
    // [...]
    BuffereImage=(BuffereImage)bvs.getImage();
    }
    
    谢谢!我刚试过,效果很好。我发现我必须添加一个Thread.sleep,因为我在创建帧后刚刚调用它,它在前一帧的顶部渲染了一个半褪色的帧(我想是win7的aero提供的)。我希望我能更好地理解引擎盖下发生的事情,但重要的是问题已经解决了。另外,谢谢你指向这个博客——看起来会很有帮助。太好了!在屏幕上显示图形后,打印更加灵活。通过这种方式,您可以以更适合您的方式操作它,并且可以选择制作您需要的任意数量的png。谢谢。你的回答帮助了我+1.顺便说一下,
    getImage
    接受两个参数。你可能想更正一下。