11using System ;
22using System . Collections . Generic ;
33using System . Linq ;
4+ using System . Runtime . InteropServices ;
45using System . Text ;
56using System . Windows ;
67using System . Windows . Controls ;
@@ -19,20 +20,73 @@ protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParam
1920 var x = ( int ) ( hitTestParameters . HitPoint . X / ActualWidth * source . PixelWidth ) ;
2021 var y = ( int ) ( hitTestParameters . HitPoint . Y / ActualHeight * source . PixelHeight ) ;
2122
22- // Copy the single pixel into a new byte array representing RGBA
23- var pixel = new byte [ 4 ] ;
24- if ( x >= source . PixelWidth )
25- x = source . PixelWidth - 1 ;
26- if ( y >= source . PixelHeight )
27- y = source . PixelHeight - 1 ;
28- source . CopyPixels ( new Int32Rect ( x , y , 1 , 1 ) , pixel , 4 , 0 ) ;
29-
30- // Check the alpha (transparency) of the pixel
31- // - threshold can be adjusted from 0 to 255
32- if ( pixel [ 3 ] < 10 )
23+ if ( x == source . PixelWidth ) x -- ;
24+ if ( y == source . PixelHeight ) y -- ;
25+
26+ var pixel = GetPixels ( source ) [ x , y ] ;
27+
28+ System . Diagnostics . Trace . WriteLine ( pixel . Alpha ) ;
29+ if ( pixel . Alpha < 5 )
3330 return null ;
3431
3532 return new PointHitTestResult ( this , hitTestParameters . HitPoint ) ;
3633 }
34+
35+ public PixelColor [ , ] GetPixels ( BitmapSource source )
36+ {
37+ if ( source . Format != PixelFormats . Bgra32 )
38+ source = new FormatConvertedBitmap ( source , PixelFormats . Bgra32 , null , 0 ) ;
39+
40+ int width = source . PixelWidth ;
41+ int height = source . PixelHeight ;
42+ PixelColor [ , ] result = new PixelColor [ width , height ] ;
43+
44+ BitmapSourceHelper . CopyPixels ( source , result , width * 4 , 0 ) ;
45+ //source.CopyPixels(result, width * 4, 0);
46+ return result ;
47+ }
48+ }
49+
50+ [ StructLayout ( LayoutKind . Sequential ) ]
51+ public struct PixelColor
52+ {
53+ public byte Blue ;
54+ public byte Green ;
55+ public byte Red ;
56+ public byte Alpha ;
57+ }
58+
59+ public static class BitmapSourceHelper
60+ {
61+ #if UNSAFE
62+ public unsafe static void CopyPixels ( this BitmapSource source , PixelColor [ , ] pixels , int stride , int offset )
63+ {
64+ fixed( PixelColor * buffer = & pixels [ 0 , 0 ] )
65+ source . CopyPixels (
66+ new Int32Rect ( 0 , 0 , source . PixelWidth , source . PixelHeight ) ,
67+ ( IntPtr ) ( buffer + offset ) ,
68+ pixels . GetLength ( 0 ) * pixels . GetLength ( 1 ) * sizeof ( PixelColor ) ,
69+ stride ) ;
70+ }
71+ #else
72+ public static void CopyPixels ( this BitmapSource source , PixelColor [ , ] pixels , int stride , int offset )
73+ {
74+ var height = source . PixelHeight ;
75+ var width = source . PixelWidth ;
76+ var pixelBytes = new byte [ height * width * 4 ] ;
77+ source . CopyPixels ( pixelBytes , stride , 0 ) ;
78+ int y0 = offset / width ;
79+ int x0 = offset - width * y0 ;
80+ for ( int y = 0 ; y < height ; y ++ )
81+ for ( int x = 0 ; x < width ; x ++ )
82+ pixels [ x + x0 , y + y0 ] = new PixelColor
83+ {
84+ Blue = pixelBytes [ ( y * width + x ) * 4 + 0 ] ,
85+ Green = pixelBytes [ ( y * width + x ) * 4 + 1 ] ,
86+ Red = pixelBytes [ ( y * width + x ) * 4 + 2 ] ,
87+ Alpha = pixelBytes [ ( y * width + x ) * 4 + 3 ] ,
88+ } ;
89+ }
90+ #endif
3791 }
3892}
0 commit comments