我正在尝试创建一个可以在SVG或JPG / PNG上绘制的程序。但是,此图仅限于大纲的内部。要获得更好的可视化效果,请查看此图片 - http://www.clker.com/cliparts/c/9/8/9/1237099922676360396kelan_Human_figure.svg
所以,在这里,我们看到一个人形,用黑线勾勒出来。 我需要的基本上是你可以在人体及其头部内部绘制,但是形状之外的所有东西都不应该被着色。
到目前为止,我尝试过使用SharpVector(A Nuget-Package)以及标准画布,但到目前为止我还没有连续播放过。此外,我无法提供任何代码示例,因为它们无论如何都没有任何帮助,至少我是这么认为的!
答案 0 :(得分:0)
编辑:我的原始答案是:
是的,这可以通过SVG图形完成。您需要提取路径 从文件中计算
Points
和缩放到的图形项目 你的画布。
现在,这很天真。仔细观察SVG格式我不得不说,即使是简单的图像,这也不容易,事实上它是一个相当高的订单......
其余的都是正确的:
..然后你可以将它们转换为
Region
并用它来剪辑 您将用于绘制的Graphics
对象。查看有关剪裁区域here on MSDN
的示例对于JPEG图像,这不是那么简单。我不确定我是怎么做的; 此刻我正在考虑外面的洪水和XORing 画布的结果,但听起来非常昂贵..
现在,这会让你离开?嗯,我想你需要得到我认为SVG数据将提供的轮廓路径。
这是一个解决方案,您可能会觉得太繁琐或完全没问题:您必须跟踪轮廓并使用跟踪结果来创建剪切区域。跟踪是一项手动任务,但对于示例文件,它可以在大约一分钟内以合理的精度完成。
以下是一些设置最小跟踪程序的例程。你需要一个pictureBox来显示图像为jpg,png或其他; .NET不直接支持svg。将PB设置为缩放并将其锚定在所有侧面。添加几个按钮即可开始..
// We collect the trace data in a list:
List<Point> points = new List<Point>();
// each mouse click adds a point
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{ points.Add(e.Location); pictureBox1.Invalidate(); }
// show all all trace points
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{ if (points.Count < 2) return;
e.Graphics.DrawCurve(Pens.OrangeRed, points.ToArray());
foreach (Point p in points)
e.Graphics.DrawRectangle(Pens.Red, p.X - 1, p.Y - 1, 3, 3);
}
// always good to have an undo button
private void cb_Undo_Click(object sender, EventArgs e)
{ if (points.Count > 0) { points.RemoveAt(points.Count-1); pictureBox1.Invalidate();} }
// start a new trace by initializing the list
private void cb_NewTrace_Click(object sender, EventArgs e)
{ points = new List<Point>(); pictureBox1.Invalidate(); }
现在我们可以收集跟踪点,我们需要一种方法来保存和加载它们。有很多方法可以做到这一点,尤其是想到了序列化。但是这些简单的功能在短缺方面很难被击败:
void savePoints(List<Point> points, string filename)
{ StringBuilder SB = new StringBuilder();
foreach (Point P in points) SB.AppendLine(P.X.ToString() + ";" + P.Y.ToString());
File.WriteAllText(filename, SB.ToString());
}
List<Point> loadPoints(string filename)
{ List<Point> points = new List<Point>();
var lines = File.ReadAllLines(filename);
foreach (string l in lines)
{
var p = l.Split(';');
points.Add(new Point(Convert.ToInt16(p[0]), Convert.ToInt16(p[1])));
}
return points;
}
使用按钮加载图像,启动跟踪,撤消单击,保存并加载跟踪数据,只需一个按钮即可测试整个图像:
// non-persistent test routine that will draw randomly in the picturebox
private void cb_Test_Click(object sender, EventArgs e)
{
using (Graphics G = pictureBox1.CreateGraphics())
{
// set up the graphicsPath
GraphicsPath path = new GraphicsPath();
path.AddCurve(points.ToArray());
// create the clipping region
Region region = new Region(path);
G.SetClip(region, CombineMode.Replace);
// now we're good to go..
// note: all drawing is done on the full range of the box!
G.FillRectangle(Brushes.GhostWhite, pictureBox1.ClientRectangle);
Random R = new Random();
int xMax = pictureBox1.ClientSize.Width;
int yMax = pictureBox1.ClientSize.Height;
for (int i = 0; i < 1000; i++)
{
int x1 = R.Next(xMax); int y1 = R.Next(yMax);
int x2 = R.Next(xMax); int y2 = R.Next(yMax);
using (Pen pen = new Pen(Color.FromArgb(
255, x1 & 255, y1 & 255, x2 * y2 & 255), 10f))
G.DrawLine(pen, x1, y1, x2, y2);
}
}
}
以下是此类曲目的预览,仅包含94个点及其测试填充: