запись графов JUNG в изображения: невозможно надежно отобразить полный график - PullRequest
5 голосов
/ 28 февраля 2011

Я использовал JUNG для визуализации некоторых простых графиков, и я хотел бы записать несколько из них в файл PNG.К сожалению, изображения часто выглядят визуализированными до того, как граф закончил рисовать, а это означает, что я получаю неполные графы, то есть графы, в которых нарисованы только несколько ребер или узлов - примерно половину времени.Рендеринг на экран работает нормально, поэтому я так озадачен.Как вы увидите ниже, я попробовал несколько обходных путей, но они не помогли.Может быть полезно знать, что базовый сервер визуализации, который я использую, не нарисует ничего полезного для 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);
    }
}

Ответы [ 2 ]

2 голосов
/ 04 июля 2011

Вы также можете использовать 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();
}
1 голос
/ 01 марта 2011

Обычно мы хотим сохранить состояние манипулируемого графа. Мы масштабируем и размещаем компоненты так, как нам нравится, а затем создаем изображение контейнера. Это может быть достигнуто так:

  1. Получить класс ScreenImage от превосходного Блог Роба Камика
  2. Передайте JPanel внутри JScrollPane или любого компонента, на котором размещен ваш график 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());
       }
    }
    
  3. Читайте также другие темы вышеупомянутого блога: -)

...