paint in GDI to contrast background?

riceman0
riceman0 used Ask the Experts™
on

Hello, if (using GDI) I need to annotate an arbitrary bitmap, I don't know what color is behind what I'm drawing.  It would be convenient if there was a brush or color that would automatically contrast the pixels behind it.  I remember this from way back in the day, BASICA had a XOR brush which would basically invert what was behind it.  Is it possible there is something BASICA could do that .NET can't?

Anyway is there any simple/fast technique in GDI to accomplish an automatic contrast (or distinction) with the background?  Obviously I could test the background, do some averaging, and choose a contrasting color but that's time consuming and exactly what im trying to avoid.
Also, alpha doesn't really work very well for this.

Any thoughts are appreciated, thanks.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2012
Top Expert 2008
Commented:
I don't believe that .NET natively support XOR drawing, but you can always find a way to p/invoke, as shown in this example:

A .NET Implementation of the ZoomIn Utility
http://www.vbaccelerator.com/home/net/code/libraries/Graphics/ZoomIn/article.asp
x77

Commented:
I use ControlPaint.DrawReversibleFrame to allow user select a an area over my control.

The first time I draw a ReversibleFrame, it shows the a visible rectangle.
When I draw same rectangle, it restore the original, then I can draw a new rectangle as user moved the mouse.

Note that this method uses Screen coordinates not control coordinates.

Note that ControlPaint includes also DrawReversibleLine.
x77
Commented:
Gdi has support to many modes when paint. (COPYPEN, MASKPEN, MERGENOTPEN ...)
You can see SetRop2 Api: http://msdn.microsoft.com/en-us/library/dd145088(v=vs.85).aspx

A Sample with SetRop2: http://www.answers.com/topic/setrop2

Note: DrawReversibleRectangle uses RopMode: R2_XORPEN (7) or R2NotXorPen (10) depending on BackColor.
Here code from this method with reflector.

     
<UIPermission(SecurityAction.LinkDemand, Window:=UIPermissionWindow.AllWindows)> _
Public Shared Sub DrawReversibleLine(ByVal start As Point, ByVal [end] As Point, ByVal backColor As Color)
    Dim nDrawMode As Integer = ControlPaint.GetColorRop(backColor, 10, 7)
    Dim handle As IntPtr = UnsafeNativeMethods.GetDCEx(New HandleRef(Nothing, UnsafeNativeMethods.GetDesktopWindow), NativeMethods.NullHandleRef, &H403)
    Dim ptr2 As IntPtr = SafeNativeMethods.CreatePen(0, 1, ColorTranslator.ToWin32(backColor))
    Dim num2 As Integer = SafeNativeMethods.SetROP2(New HandleRef(Nothing, handle), nDrawMode)
    Dim ptr3 As IntPtr = SafeNativeMethods.SelectObject(New HandleRef(Nothing, handle), New HandleRef(Nothing, UnsafeNativeMethods.GetStockObject(5)))
    Dim ptr4 As IntPtr = SafeNativeMethods.SelectObject(New HandleRef(Nothing, handle), New HandleRef(Nothing, ptr2))
    SafeNativeMethods.MoveToEx(New HandleRef(Nothing, handle), start.X, start.Y, Nothing)
    SafeNativeMethods.LineTo(New HandleRef(Nothing, handle), [end].X, [end].Y)
    SafeNativeMethods.SetROP2(New HandleRef(Nothing, handle), num2)
    SafeNativeMethods.SelectObject(New HandleRef(Nothing, handle), New HandleRef(Nothing, ptr3))
    SafeNativeMethods.SelectObject(New HandleRef(Nothing, handle), New HandleRef(Nothing, ptr4))
    SafeNativeMethods.DeleteObject(New HandleRef(Nothing, ptr2))
    UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, New HandleRef(Nothing, handle))
End Sub

Open in new window


To Get screen coordinates, use  Control.PointToScreen where control is your control.


'If DragMode, When Left Mouse Down, Start Drag Operation
    Private Sub PrvCtl_MouseDown (ByVal sender As Object, ByVal e As MouseEventArgs) Handles PrvCtl.MouseDown
        If DragMode Then
            DragMode = False
            rcold = New Rectangle (PrvCtl.PointToScreen (New Point (0, e.Y)), New Size (PrvCtl.Width, 0))
            PrvCtl.AllowDrop = True
            PrvCtl.DoDragDrop (New DataObject ("e", e), DragDropEffects.Move)
        End If
    End Sub

Open in new window

Author

Commented:
Thanks, both look promising.  I will post back with some sort of solution/resolution.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial