在C#中从.dot文件创建图像

时间:2011-12-13 20:40:57

标签: c# graphviz

我正在构建一个.dot文件来表示有向无环图。

我需要从这个graph.dot文件生成一个图像(使用C#),这样我就可以在我的应用程序的图片框中显示图像。我应该使用什么库?

在命令提示符中使用GraphViz的命令:

dot -Tpng graph.dot -o graph.png 

我能够很好地生成图像,所以我知道我的.dot文件的格式是正确的。

谢谢。

4 个答案:

答案 0 :(得分:4)

感谢@marapet将我指向David Brown的项目。

我已将样本下载到:David Brown's Implicit Operator

样本效果很好。

我将所需的代码复制到我的项目中。我不得不将.NET目标框架从4.0更改为3.5,但这不是问题。

到目前为止,代码从未崩溃过。 (即使其他人报告了问题。)

<强>更新

大卫·布朗的网站似乎已经关闭,所以我已经用我从网站上获取的代码更新了这个答案。

//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);
        }
    }
}

答案 1 :(得分:2)

您可以使用Process启动dot.exe

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

 Process.Start(startInfo);

答案 2 :(得分:2)

这是一个很难的,我找到了一个名为GrapVizNet的GraphViz的.NET包装器,这可能使它成为可能。

更有趣的是使用PInvoke创建自己的包装器。我相信this正是您所需要的。不是最优雅的解决方案,但可能是你唯一的解决方案。

答案 3 :(得分:0)

This other library called Graphviz.NetWrapper允许您使用C#代码构建图形,使用graphviz库计算布局,并使用C#读取布局信息(例如位置等),或者直接生成图像文件。

通过这种方式,您可以选择是嵌入原始图像,还是要根据提供给您的布局信息自己绘制图像。