PictureBox – 处理图像非透明区域上的点击事件

我必须在C#中创建一个窗体,其中两个PictureBox重叠。 TopPictureBox包含一个透明的png图片。 默认情况下,可以通过单击TopPictureBox中图像的任何可见或透明区域来单击TopPictureBox。 但是我想通过单击图像的可见区域而不是透明区域来单击TopPictureBox。 另外我想让光标只在图像的可见区域上改变,而不是在透明区域。

这有什么办法吗?

我正在使用此代码使TopPictureBox透明。

TopPictureBox.BackColor = Color.Transparent; 

谢谢你的帮助。

在此处输入图像描述

检查PictureBox的位置是否Transparent取决于PictureBoxImageSizeMode属性。

您不能简单地使用Bitmap GetPixel ,因为基于SizeMode的图像位置和大小是不同的。 您应该首先根据SizeMode检测Image的大小和位置:

 public bool HitTest(PictureBox control, int x, int y) { var result = false; if (control.Image == null) return result; var method = typeof(PictureBox).GetMethod("ImageRectangleFromSizeMode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var r = (Rectangle)method.Invoke(control, new object[] { control.SizeMode }); using (var bm = new Bitmap(r.Width, r.Height)) { using (var g = Graphics.FromImage(bm)) g.DrawImage(control.Image, 0, 0, r.Width, r.Height); if (r.Contains(x, y) && bm.GetPixel(x - rX, y - rY).A != 0) result = true; } return result; } 

然后你可以简单地使用HitTest方法来检查鼠标是否在PictureBox的非透明区域上:

 private void pictureBox1_MouseMove(object sender, MouseEventArgs e) { if (HitTest(pictureBox1,eX, eY)) pictureBox1.Cursor = Cursors.Hand; else pictureBox1.Cursor = Cursors.Default; } private void pictureBox1_MouseClick(object sender, MouseEventArgs e) { if (HitTest(pictureBox1, eX, eY)) MessageBox.Show("Clicked on Image"); } 

BackColor设置为Color.Transparent只会使PictureBox相对于它的父级透明。 例如,如果在Form有2个PictureBox设置透明背面颜色,则只需要看到窗体的背景。 要制作支持透明背景的PictureBox ,您应该自己绘制控件背后的内容。 你可以在这篇文章中找到一个TransparentPictureBox : 如何使用c#创建两个透明层?

一种方法是检查用户单击的像素的颜色是否与表单的背景颜色相同。 如果是,则用户单击透明区域。

(注意:正如Reza所提到的,此代码只能在没有重叠PictureBox的情况下使用,即仅当图像的透明区域与Form的背景颜色相同时)

 Color pixelColour; private void myPicturebox_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { pixelColour = ((Bitmap)myPicturebox.Image).GetPixel(point.X, point.Y); if (this.BackColor == pixelColour) { // User clicked on transparent area } else { // User clicked on image } } }