2011-12-13 2 views
5

Я создаю файл .dot для представления ориентированного ациклического графа.Создать изображение из .dot файла в C#

Мне нужно сгенерировать изображение из этого файла graph.dot (используя C#), чтобы я мог показывать изображение в Picture Box в своем приложении. Какую библиотеку я должен использовать?

Использование команды GraphViz в командной строке:

dot -Tpng graph.dot -o graph.png 

Я способен генерировать штраф изображения, так что я знаю, что форматирование моего файла .dot правильно.

спасибо.

+0

Итак, я предполагаю, что вы не хотите просто запускать утилиту dot из своего приложения C#? – RQDQ

+0

Нет, это не то, что я хочу. – Rachel

ответ

4

Спасибо @marapet за указание на проект Дэвида Брауна.

Я скачал образец на: David Brown's Implicit Operator

Пробу работает хорошо.

Я скопировал требуемый код в свой проект. Мне пришлось изменить мою .NET Target Framework с 4.0 до 3.5, но это не проблема.

До сих пор код никогда не разбивался. (Даже если другие люди сообщили о проблемах.)

UPDATE

сайт Дэвид Браун, кажется, вниз, так что я обновил этот ответ с кодом я взял с сайта.

//Code for this Class downloaded from http://implicitoperator.com/blog/2010/4/11/graphviz-c-sample.html 

public class GraphViz 
{ 

    public const string LIB_GVC = "gvc.dll"; 
    public const string LIB_GRAPH = "graph.dll"; 
    public const int SUCCESS = 0; 

    /// <summary> 
    /// Creates a new Graphviz context. 
    /// </summary> 
    [DllImport(LIB_GVC)] 
    public static extern IntPtr gvContext(); 

    /// <summary> 
    /// Reads a graph from a string. 
    /// </summary> 
    [DllImport(LIB_GRAPH)] 
    public static extern IntPtr agmemread(string data); 

    /// <summary> 
    /// Renders a graph in memory. 
    /// </summary> 
    [DllImport(LIB_GVC)] 
    public static extern int gvRenderData(IntPtr gvc, IntPtr g, 
     string format, out IntPtr result, out int length); 

    /// <summary> 
    /// Applies a layout to a graph using the given engine. 
    /// </summary> 
    [DllImport(LIB_GVC)] 
    public static extern int gvLayout(IntPtr gvc, IntPtr g, string engine); 

    /// <summary> 
    /// Releases the resources used by a layout. 
    /// </summary> 
    [DllImport(LIB_GVC)] 
    public static extern int gvFreeLayout(IntPtr gvc, IntPtr g); 

    /// <summary> 
    /// Releases a context's resources. 
    /// </summary> 
    [DllImport(LIB_GVC)] 
    public static extern int gvFreeContext(IntPtr gvc); 

    /// <summary> 
    /// Releases the resources used by a graph. 
    /// </summary> 
    [DllImport(LIB_GRAPH)] 
    public static extern void agclose(IntPtr g); 

    public static Image RenderImage(string source, string layout, string format) 
    { 
     // Create a Graphviz context 
     IntPtr gvc = gvContext(); 
     if (gvc == IntPtr.Zero) 
      throw new Exception("Failed to create Graphviz context."); 

     // Load the DOT data into a graph 
     IntPtr g = agmemread(source); 
     if (g == IntPtr.Zero) 
      throw new Exception("Failed to create graph from source. Check for syntax errors."); 

     // Apply a layout 
     if (gvLayout(gvc, g, layout) != SUCCESS) 
      throw new Exception("Layout failed."); 

     IntPtr result; 
     int length; 

     // Render the graph 
     if (gvRenderData(gvc, g, format, out result, out length) != SUCCESS) 
      throw new Exception("Render failed."); 

     // Create an array to hold the rendered graph 
     byte[] bytes = new byte[length]; 

     // Copy the image from the IntPtr 
     Marshal.Copy(result, bytes, 0, length); 

     // Free up the resources 
     gvFreeLayout(gvc, g); 
     agclose(g); 
     gvFreeContext(gvc); 

     using (MemoryStream stream = new MemoryStream(bytes)) 
     { 
      return Image.FromStream(stream); 
     } 
    } 
} 
+0

Отлично!Не могли бы вы поделиться тем, какую ОС и версию Graphviz вы используете? – marapet

+1

@marapet Я использую Windows 7 Professional 64-bit с пакетом обновления 1 (SP1). Версия GraphViz - 2.28.0, загружаемая с http://www.graphviz.org/Download_windows.php. Код все еще не разбился :) – Rachel

+0

Эй, у вас все еще есть образец? Веб-сайт не работает, и мне нужно посмотреть на этот код. – pmichna

2

Вы можете использовать процесс, чтобы начать dot.exe

ProcessStartInfo startInfo = new ProcessStartInfo("dot.exe"); 
startInfo.Arguments = "-Tpng graph.dot -o graph.png"; 

Process.Start(startInfo); 
+0

Благодарим вас за ввод. Это работает, но это не то, что я ищу. Я бы предпочел, если бы я мог использовать некоторую библиотеку, у которой есть метод, который принимает .dot файл как параметр (или String, найденный в файле) и возвращает изображение. – Rachel

+0

@ Рэйчел не проблема, немного выдумки, но все, что я мог придумать. –

+0

+1 Да, это взломать. Но иногда такой взлом может вывести вас из привязки. – user

2

Это трудно один, я нашел .NET обертка для GraphViz называется GrapVizNet, который, возможно, делает это возможным.

Более интересный создает вашу обертку с помощью PInvoke. Я считаю, что this - это именно то, что вам нужно. Не самое изящное решение, но, возможно, единственное, что у вас есть.

+2

Проект Дэвида Брауна действительно отвечает именно тому, что задают в вопросе. Единственная проблема заключается в том, что в последних версиях появилась ошибка: см. Также вопрос Дэвида Брауна о SO: http://stackoverflow.com/a/4876966/63733 – marapet

+0

@marapet +1 для просмотра этого. Быстрый поиск не дает мне никакой информации о том, исправлена ​​ли эта ошибка. Вам нужно попробовать, чтобы узнать. –

+0

Это не так, по крайней мере, не соответствует статусу отчетов об ошибках ([1870] (http://www.graphviz.org/bugs/b1870.html) и [1775] (http: //www.graphviz .org/bugs/b1775.html)), поданной @David Brown. Кто-то предлагает построить graphviz сам по окнам с одним и тем же компилятором - не знаю, помогает ли это. – marapet

Смежные вопросы