2016-02-09 37 views
-3

我正在创建一个gannt图表,以显示数百个日历中的单个订单实例,目前使用算法绘制线条和矩形创建网格,问题是我是位图变得越来越大,占用内存,我尝试了多种不同的方法,包括绘制一半大小的位图并扩展它们(出来非常模糊)并且仍然很大。C#中的SVG,绘制多个复杂的矩形

我希望能够绘制SVG,因为我认为绘制大型简单形状的东西应该与位图相比显着减小大小。

问题是我无法找到msdn上的任何东西,包括任何类型的绘图svgs的c#库,我不想使用外部代码。

我需要在XAML中创建它还是存在类似于位图绘制的库? current bitmap version, either going out of bounds on the max size or just freezing because system is out of memory

回答

0

Windows窗体= GDI/GDI +

WPF/XAML = DirectX的(如果可能)

最好的选择是去与支撑可伸缩矢量图形(未一样WPF/XAML。 svg文件格式)

您需要第三方代码才能在WinForms中执行SVG。


如果你坚持使用WinForms,那么位图是真正实现这一目标的唯一方法。看看PixelFormat - 例如,您可以通过使用每像素比特数较少的格式来减少内存中位图的大小。

+0

我试图用位图缩小尺寸,但要改变像素格式,你不能使用绘图,因为索引像素格式不允许从我可以看到哪些本来是较小的,我尝试绘制图像在一个较小的然后缩放比较低质量的图像,但是由于某种原因,我无法理解位图放大时的模糊效果。 – oisins

0

没有必要使用外部工具或SVG。通过一些简单的数学运算,您可以轻松地呈现想要显示的必要部分。您只需要知道网格大小,日期范围和视图中可见的订单项的范围。让我们称他们为:

DateTime dispStartDate; 
DateTime dispEndDate; 
int dispStartItem; 
int dispEndItem; 
int GridSize = 10; //nifty if you'd like a magnification factor 

我们还假设你有一个甘特图项目类:

class gItem 
{ 
    DateTime StartDate{ get; set; } 
    DateTime EndDate{ get; set; } 
    int LineNumber{ get; set; } 
    int Length { get { return EndDate - StartDate; } } 
    //some other code and stuff you'd like to add 
} 

现在,您需要包含所有的甘特图条目列表:

List<gItem> GanttItems; 

现在你应该为每个上述变量赋值,现在是时候生成一个矩形列表,该矩形列表在视图中可见并绘制它们:

List<Rectangle> EntryRects = new List<Rectangle>(); 

void UpdateDisplayBounds() 
{  
    foreach(gItem gEntry in GanttItems) 
    { 
     if(gEntry.StartDate < dispEndDate && gEntry.EndDate > dispStartDate 
      && gEntry.LineNumber >= dispStartItem && gEntry.LineNumber <= dispEndItem) 
     { 
      int x = (gEntry.StartDate - dispStartDate) * GridSize; 
      int y = (gEntry.LineNumber - dispStartItem) * GridSize; 
      int width = gEntry.Length * GridSize; 
      int height = GridSize; 
      EntryRects.Add(new Rectangle(x, y, width, height); 
     } 
    }  
} 

现在,您只有可以呈现的显示边界内的矩形列表。所以我们来画一下:

void DrawRectangles(Graphics canvas)//use a picturebox's graphics handler or something for the canvas 
{ 
    canvas.Clear(this.BackColor); 
    using(SolidBrush b = new SolidBrush(Color.Blue)) //Choose your color 
    { 
     foreach(Rectangle r in EntryRects) 
     { 
      canvas.FillRectangle(b, r); 
     } 
    } 
} 

上面的代码应该让你开始。有了这个,你可以根据请求渲染一个矩形列表,并且内存中唯一的图像占用空间是当前显示的空间。

+0

你的Gannt列表字面上是我目前所拥有的,我使用数学来绘制我的位图,目前以非常相似的方式,我会尝试这种方法。谢谢 – oisins