Solved

paint in GDI to contrast background?

Posted on 2011-09-03
4
419 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
  • 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

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

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

This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

813 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now