繁体   English   中英

PictureBox-处理图像非透明区域上的Click事件

[英]PictureBox - Handle Click Event on Non-Transparent Area of Image

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

有什么办法可以做这些?

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

TopPictureBox.BackColor = Color.Transparent;

谢谢你的帮助。

在此处输入图片说明

检查,如果在一个位置PictureBoxTransparent或不依赖于ImageSizeMode的属性PictureBox

您不能简单地使用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 - r.X, y - r.Y).A != 0)
            result = true;
    }
    return result;
}

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

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (HitTest(pictureBox1,e.X, e.Y))
        pictureBox1.Cursor = Cursors.Hand;
    else
        pictureBox1.Cursor = Cursors.Default;
}

private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
    if (HitTest(pictureBox1, e.X, e.Y))
        MessageBox.Show("Clicked on Image");
}

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

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

(注意:如Reza所述,仅当没有重叠的PictureBox时,即仅当图像的透明区域的颜色与窗体的背景颜色相同时,才可以使用此代码)

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
     }
   }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM