Solved

paint in GDI to contrast background?

Posted on 2011-09-03
4
436 Views
Last Modified: 2012-05-12

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.
0
Comment
Question by:riceman0
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
4 Comments
 
LVL 96

Accepted Solution

by:
Bob Learned earned 250 total points
ID: 36480495
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
0
 
LVL 15

Expert Comment

by:x77
ID: 36480683
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.
0
 
LVL 15

Assisted Solution

by:x77
x77 earned 250 total points
ID: 36480852
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

0
 

Author Closing Comment

by:riceman0
ID: 36511616
Thanks, both look promising.  I will post back with some sort of solution/resolution.
0

Featured Post

Tutorials alone can't teach real engineering

So we built better training tools.

-Hands-on Labs
-Instructor Mentoring
-Scenario-Based Tests
-Dedicated Cloud Servers

All at your fingertips. What are you waiting for?

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

691 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question