C# 改进我的问题,这是目前为止最好的答案,但不是我的确切意思。我能想到的一种可能性是将PictureBox子类化,修改消息处理程序以允许点击,然后使用子类显示“真实”图像。请稍等(一两分钟),你能重新检查一下主柱吗?我认为这解释得更好。@mjw comment
C# 改进我的问题,这是目前为止最好的答案,但不是我的确切意思。我能想到的一种可能性是将PictureBox子类化,修改消息处理程序以允许点击,然后使用子类显示“真实”图像。请稍等(一两分钟),你能重新检查一下主柱吗?我认为这解释得更好。@mjw comment,c#,winforms,controls,transparency,region,C#,Winforms,Controls,Transparency,Region,改进我的问题,这是目前为止最好的答案,但不是我的确切意思。我能想到的一种可能性是将PictureBox子类化,修改消息处理程序以允许点击,然后使用子类显示“真实”图像。请稍等(一两分钟),你能重新检查一下主柱吗?我认为这解释得更好。@mjw comment中的链接解释了如何使用WinForms执行此操作-您需要使用GraphicsPath修改关联控件的Region属性,以便在2中绘制可以为该控件注册单击的位置。如果我需要改变它的一部分,我应该重新修补图像,对吗?没错。这是一个快速的操作,所以不要
改进我的问题,这是目前为止最好的答案,但不是我的确切意思。我能想到的一种可能性是将
PictureBox
子类化,修改消息处理程序以允许点击,然后使用子类显示“真实”图像。请稍等(一两分钟),你能重新检查一下主柱吗?我认为这解释得更好。@mjw comment中的链接解释了如何使用WinForms执行此操作-您需要使用GraphicsPath
修改关联控件的Region
属性,以便在2中绘制可以为该控件注册单击的位置。如果我需要改变它的一部分,我应该重新修补图像,对吗?没错。这是一个快速的操作,所以不要担心!您需要维护带有搜索点的搜索列表,并且应注意只保留每个图像的一个副本。.列表>图像>是否是存储图像的好选择,而不是ImageList?在程序运行时存储?是的,所有图像都是独立的。它们不会编译成exe,但这可能不是您想要的。
public partial class Form1 : Form {
readonly Color mask = Color.Black;
public Form1() {
InitializeComponent();
}
private void pictureBox1_Click(object sender, EventArgs e) {
var me = e as MouseEventArgs;
using (var bmp = new Bitmap(pictureBox1.Image)) {
if (me.X < pictureBox1.Image.Width && me.Y < pictureBox1.Image.Height) {
var colorAtMouse = bmp.GetPixel(me.X, me.Y);
if (colorAtMouse.ToArgb() == mask.ToArgb()) {
MessageBox.Show("Mask clicked!");
}
}
}
}
}
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);
}
List<Tuple<Image, Point>> imgList = new List<Tuple<Image, Point>>();
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];
}
}
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();
}