2011-12-13 34 views
5

Tôi đang xây dựng một tệp .dot để biểu diễn một biểu đồ tuần hoàn hướng.Tạo hình ảnh Từ tập tin .dot trong C#

Tôi cần tạo hình ảnh từ tệp graph.dot này (sử dụng C#) để tôi có thể hiển thị hình ảnh trong Hộp hình trong ứng dụng của tôi. Tôi nên sử dụng thư viện nào?

Sử dụng lệnh GraphViz tại dấu nhắc lệnh:

dot -Tpng graph.dot -o graph.png 

tôi có thể tạo ra các hình ảnh tốt, vì vậy tôi biết rằng định dạng của tập tin Dot của tôi là đúng.

Cảm ơn bạn.

+0

Vì vậy, tôi giả sử bạn không muốn chỉ chạy tiện ích dấu chấm từ ứng dụng C# của bạn? – RQDQ

+0

Không, đó không phải là điều tôi muốn. – Rachel

Trả lời

4

Cảm ơn bạn @marapet đã chỉ cho tôi dự án của David Brown.

Tôi đã tải xuống mẫu tại: David Brown's Implicit Operator

Mẫu hoạt động tốt.

Tôi đã sao chép mã được yêu cầu vào dự án của mình. Tôi phải thay đổi .NET Target Framework từ 4.0 sang 3.5, nhưng đó không phải là vấn đề.

Cho đến nay, mã chưa bao giờ bị lỗi. (Mặc dù những người khác đã thông báo vấn đề này.)

CẬP NHẬT

website David Brown có vẻ là xuống vì vậy tôi đã cập nhật câu trả lời này với mã tôi đã lấy từ trang web.

//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

Thật tuyệt vời!Bạn có nhớ chia sẻ phiên bản hệ điều hành và đồ thị bạn đang sử dụng không? – marapet

+1

@marapet Tôi đang sử dụng Windows 7 Professional 64 bit với SP1. Phiên bản GraphViz là 2.28.0, được tải xuống từ http://www.graphviz.org/Download_windows.php. Mã vẫn chưa bị lỗi :) – Rachel

+0

Hey, bạn vẫn có mẫu? Trang web đã ngừng hoạt động và tôi cần xem mã đó. – pmichna

2

Bạn có thể sử dụng Process để bắt đầu dot.exe

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

Process.Start(startInfo); 
+0

Cảm ơn bạn đã nhập. Điều đó không hiệu quả, nhưng đó không phải là những gì tôi đang tìm kiếm. Tôi thích nếu tôi có thể sử dụng một số thư viện mà có một phương pháp mà có các tập tin .dot như một tham số (hoặc String tìm thấy trong tập tin) và trả về hình ảnh. – Rachel

+0

@Rachel không có vấn đề, một chút của một fudge nhưng tất cả tôi có thể nghĩ đến. –

+0

+1 Vâng, đó là một hack. Nhưng đôi khi một hack như thế này có thể giúp bạn thoát khỏi sự ràng buộc. – user

2

Đây là một khó khăn một, tôi tìm thấy một wrapper NET cho GraphViz gọi GrapVizNet mà có thể làm cho nó có thể.

Một điều thú vị hơn là tạo một trình bao bọc cho chính bạn với PInvoke. Tôi tin rằng this chính xác là những gì bạn cần. Không phải là giải pháp thanh lịch nhất nhưng có lẽ chỉ có bạn nhận được.

+2

Dự án của David Brown thực sự chính xác những gì được hỏi trong câu hỏi. Vấn đề duy nhất là có vẻ như có lỗi trong các phiên bản gần đây - xem thêm câu hỏi của David Brown về SO: http://stackoverflow.com/a/4876966/63733 – marapet

+0

@marapet +1 để xem câu hỏi đó. Tìm kiếm nhanh không cung cấp cho tôi bất kỳ thông tin nào cho dù lỗi này đã được sửa chưa. Bạn sẽ phải thử nó để tìm hiểu. –

+0

Nó đã không - ít nhất là không theo tình trạng của các báo cáo lỗi ([1870] (http://www.graphviz.org/bugs/b1870.html) và [1775] (http: //www.graphviz .org/bugs/b1775.html)) được gửi bởi @David Brown. Có người đề nghị xây dựng graphviz chính nó trên các cửa sổ với trình biên dịch tương tự - không biết liệu có giúp. – marapet

Các vấn đề liên quan