我正在创建一个gannt图表来显示单个订单实例的数百个日历,目前使用算法绘制线条和矩形来创建网格,问题是我的位图正变得越来越大占用ram,我尝试了多种不同的方法,包括绘制半尺寸的位图并将它们放大(出现可怕的模糊)并且仍然很大。
我希望能够绘制SVG,因为我想要绘制大型简单形状的东西应该比位图显着减小尺寸。
问题是我无法在msdn上找到任何包含用于绘制svgs的任何类型的c#库而我不想使用外部代码。
答案 0 :(得分:0)
Windows Forms = GDI / GDI +
WPF / XAML = DirectX(如果可能)
最好的办法是使用支持可缩放矢量图形的WPF / XAML(与.svg文件格式不同)
您需要第三方代码才能在WinForms中执行SVG。
如果您坚持使用WinForms,那么位图是实现这一目标的唯一方法。看一下PixelFormat - 你可以通过使用一个需要更少每像素位数的格式来缩小内存中位图的大小。
答案 1 :(得分: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);
}
}
}
上面的代码可以帮助您入门。使用此功能,您可以根据请求呈现矩形列表,并且内存中唯一占用空间的图像是当前显示的矩形。