question

LT-6413 avatar image
0 Votes"
LT-6413 asked LT-6413 answered

mouse move events only on semi transparent imagebrush

Hi!
I would like to create a custom button control with partially transparent pictures as normal and mouse over state. I want the user to be able to set the pictures himself and also be able to adjust the tiling/stretch/offset. Now I need to figure out some way to trigger e.g. the mousemove event, but not on the transparent areas.
I was thinking about using imagecache, getting the bitmap from there and checking for the color on pixel but it's not very efficient on mousemove.

Is there possibly a better solution?

windows-wpf
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

you could use vector graphics, I use all the time for my buttons, checkboxes, etc., instead of image and you don't get those events fired when mouse is over the transparent/hollow area of those graphics.

1 Vote 1 ·

1 Answer

LT-6413 avatar image
1 Vote"
LT-6413 answered

Thanks for the answer! I kind of had blended out the possibility of vectors and it got me some points i ll probably research. regarding this I have now implemented the following and it works without any performance paranoia i might have had,
(found on stackoverflow)
in mouse move simply checking bool transp = pxlColor == "#00000000";



   public static System.Windows.Media.Color GetPixelColor(Visual visual, System.Windows.Point pt)
     {
         System.Windows.Point ptDpi = getScreenDPI(visual);

         System.Windows.Size srcSize = VisualTreeHelper.GetDescendantBounds(visual).Size;

         //Viewbox uses values between 0 & 1 so normalize the Rect with respect to the visual's Height & Width
         Rect percentSrcRec = new Rect(pt.X / srcSize.Width, pt.Y / srcSize.Height,
                                       1 / srcSize.Width, 1 / srcSize.Height);

         //var bmpOut = new RenderTargetBitmap(1, 1, 96d, 96d, PixelFormats.Pbgra32); //assumes 96 dpi
         var bmpOut = new RenderTargetBitmap((int)(ptDpi.X / 96d),
                                             (int)(ptDpi.Y / 96d),
                                             ptDpi.X, ptDpi.Y, PixelFormats.Default); //generalized for monitors with different dpi

         DrawingVisual dv = new DrawingVisual();
         using (DrawingContext dc = dv.RenderOpen())
         {
             dc.DrawRectangle(new VisualBrush { Visual = visual, Viewbox = percentSrcRec },
                              null, //no Pen
                              new Rect(0, 0, 1d, 1d));
         }
         bmpOut.Render(dv);

         var bytes = new byte[4];
         int iStride = 4; // = 4 * bmpOut.Width (for 32 bit graphics with 4 bytes per pixel -- 4 * 8 bits per byte = 32)
         bmpOut.CopyPixels(bytes, iStride, 0);

         return System.Windows.Media.Color.FromArgb(bytes[0], bytes[1], bytes[2], bytes[3]);
     }

     public static System.Windows.Point getScreenDPI(Visual v)
     {
         //System.Windows.SystemParameters
         PresentationSource source = PresentationSource.FromVisual(v);
         System.Windows.Point ptDpi;
         if (source != null)
         {
             ptDpi = new System.Windows.Point(96.0 * source.CompositionTarget.TransformToDevice.M11,
                                96.0 * source.CompositionTarget.TransformToDevice.M22);
         }
         else
             ptDpi = new System.Windows.Point(96d, 96d); //default value.

         return ptDpi;
     }
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.