这两种方法解决这个问题:
与
Regions
第一种方法涉及创建控件,e.g PictureBoxes
或,其具有的图像的形状和仅该形状内部点击。
这很不错,只要你有权访问构成形状的矢量轮廓。
这里是制约一个Panel
可见&点击Region
从跟踪点列表创建了一个形状不规则的斑点一个例子:不幸的是使从一个Region
List<Point> points = new List<Point>();
points.Add(new Point(50,50));points.Add(new Point(60,65));points.Add(new Point(40,70));
points.Add(new Point(50,90));points.Add(new Point(30,95));points.Add(new Point(20,60));
points.Add(new Point(40,55));
using (GraphicsPath gp = new GraphicsPath())
{
gp.AddClosedCurve(points.ToArray());
panel1.Region = new Region(gp);
}
包含在其中的要点将不起作用;想象一个Region
作为矢量形状的列表,这些由点组成,但仅用于创建包含矢量,而不是像素。
您可以跟踪形状,但这是很多工作,而且imo不值得它。
所以,如果你不具备矢量形状:去的第二种方法:
这会假设你有图片(可能png格式),这是在没有点击应该接受所有的斑点透明。
最简单和最有效的方法是将它们与它们应该位于的点一起放入一个列表中;然后,每当它们发生变化时,将它们全部绘制成一张图像,您可以将其分配给一个PictureBox.Image
。
这是一个Mouseclick
事件,它将搜索图像列表中最顶端的Image
以查找被点击的图像。与他们的位置将它们组合起来我用一个元组列表:
List<Tuple<Image, Point>> imgList = new List<Tuple<Image, Point>>();
我们通过这个列表中搜索每个MouseClick
:
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
int found = -1;
// I search backward because I drew forward:
for (int i = imageList1.Images.Count - 1; i >= 0; i--)
{
Bitmap bmp = (Bitmap) imgList[i].Item1;
Point pt = (Point) imgList[i].Item2;
Point pc = new Point(e.X - pt.X, e.Y - pt.Y);
Rectangle bmpRect = new Rectangle(pt.X, pt.Y, bmp.Width, bmp.Height);
// I give a little slack (11) but you could also check for > 0!
if (bmpRect.Contains(e.Location) && bmp.GetPixel(pc.X, pc.Y).A > 11)
{ found = i; break; }
}
// do what you want with the found image..
// I show the image in a 2nd picBox and its name in the form text:
if (found >= 0) {
pictureBox2.Image = imageList1.Images[found];
Text = imageList1.Images.Keys[found];
}
}
这里是我组合的图像为一体。请注意,对于测试,我已将它们添加到ImageList
对象。这具有严重的缺点,因为所有图像都被缩放到一个普通尺寸。你可能会想创建一个你自己的正确列表!
Bitmap patchImages()
{
Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height);
imgList.Clear();
Random R = new Random(1);
using (Graphics G = Graphics.FromImage(bmp))
{
foreach (Image img in imageList1.Images)
{
// for testing: put each at a random spot
Point pt = new Point(R.Next(333), R.Next(222));
G.DrawImage(img, pt);
// also add to the searchable list:
imgList.Add(new Tuple<Image, Point>(img, pt));
}
}
return bmp;
}
我把它叫做启动:
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.Image = patchImages();
}
旁白:所有的图像绘制成一个通过这种方式,也是唯一一个可以让你自由的重叠图像。 Winforms
不支持与重叠控件的真实透明度。并且为每个形状测试一个Pixel
(最多)也是非常快的。
Webforms,Windows Forms,WPF,GTK ...? – jdphenix
WinForms,对不起。 –
不用担心。它只会帮助你得到答案。 – jdphenix