我在WPF中有一个Image
控件,其中包含一个包含大量透明像素的图像。现在,每当我在MouseDown
控件的完整矩形区域内单击时,Image
上的Image
事件就会触发。我想要一些方法来检测鼠标是否发生在图像的不透明部分。
这样做的最佳方式是什么?
答案 0 :(得分:13)
使用this answer中的技术,您可以从Image
派生,以创建OpaqueClickableImage
,只响应图像的非透明区域中的点击测试:
public class OpaqueClickableImage : Image
{
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
var source = (BitmapSource)Source;
// Get the pixel of the source that was hit
var x = (int)(hitTestParameters.HitPoint.X / ActualWidth * source.PixelWidth);
var y = (int)(hitTestParameters.HitPoint.Y / ActualHeight * source.PixelHeight);
// Copy the single pixel into a new byte array representing RGBA
var pixel = new byte[4];
source.CopyPixels(new Int32Rect(x, y, 1, 1), pixel, 4, 0);
// Check the alpha (transparency) of the pixel
// - threshold can be adjusted from 0 to 255
if (pixel[3] < 10)
return null;
return new PointHitTestResult(this, hitTestParameters.HitPoint);
}
}
添加此类后,只需像常规图像一样使用它:
<utils:OpaqueClickableImage Name="image" Source="http://entropymine.com/jason/testbed/pngtrans/rgb8_t_bk.png" Stretch="None"/>
答案 1 :(得分:3)
public class OpaqueClickableImage : Image
{
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
var source = (BitmapSource)Source;
var x = (int)(hitTestParameters.HitPoint.X / ActualWidth * source.PixelWidth);
var y = (int)(hitTestParameters.HitPoint.Y / ActualHeight * source.PixelHeight);
if (x == source.PixelWidth)
x--;
if (y == source.PixelHeight)
y--;
var pixels = new byte[4];
source.CopyPixels(new Int32Rect(x, y, 1, 1), pixels, 4, 0);
if (pixels[3] < 1) return null;
return new PointHitTestResult(this, hitTestParameters.HitPoint);
}
}