开发者

WPF: Detect Image click only on non-transparent portion

I have an Image control in WPF which contains an image with lots of transparent pixels. Right now,开发者_如何学Python the MouseDown event on Image fires whenever I click within the full rectangular region of the Image control. I would like some way to detect if the mouse click occurred on a nontransparent portion of the image.

What would be the best way of doing this?


Using the technique in this answer you can derive from Image to create an OpaqueClickableImage that only responds to hit-testing in sufficiently non-transparent areas of the image:

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

after adding this class, just use it like a regular image:

<utils:OpaqueClickableImage Name="image" Source="http://entropymine.com/jason/testbed/pngtrans/rgb8_t_bk.png" Stretch="None"/>


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);
        
        return (pixels[3] < 1) ? null : new PointHitTestResult(this, hitTestParameters.HitPoint);
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜