WPF:检测图像仅在非透明部分上单击

Bra*_*ley 8 wpf image wpf-controls

Image在WPF中有一个控件,其中包含一个包含大量透明像素的图像.现在,每当我在控件的完整矩形区域内单击时,MouseDown事件Image就会触发Image.我想要一些方法来检测鼠标是否发生在图像的不透明部分.

这样做的最佳方式是什么?

Ric*_*key 14

使用此答案中的技术,您可以从中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);
    }
}
Run Code Online (Sandbox Code Playgroud)

添加此类后,只需像常规图像一样使用它:

<utils:OpaqueClickableImage Name="image" Source="http://entropymine.com/jason/testbed/pngtrans/rgb8_t_bk.png" Stretch="None"/>
Run Code Online (Sandbox Code Playgroud)

  • 我实际上已经看到这个失败,因为 `x` 或 `y` 将在 `source` 的 `PixelWidth` 或 `PixelHeight` 之外。可以将计算四舍五入,或者说,如果`x&gt;= PixelWidth: x = PixelWidth` (2认同)