How to Draw a Gradient Line/Spline?

I am trying to create a gradient line and spline on a wxpython DC (I’ve only included the line for this example).

The following code produces the below result:

        r1  = wx.Rect(0, 0, 150, 150)
        dc.GradientFillLinear(r1, wx.Colour("#fff"), wx.Colour("#000"))
        r2  = wx.Rect(150, 150, 150, 150)
        dc.GradientFillConcentric(r2, wx.Colour("#fff"), wx.Colour("#000"), wx.Point(5, 5))
        dc.DrawLine(0, 0, 100, 200)

image

How can I get just a gradient line/spline?

You can use MemoryDC to draw to bitmaps in memory.

  1. Create a mask bitmap. Black=masked, White=unmasked.
  2. Draw a bunch of white lines/splines to this bitmap.
  3. Create a gradient bitmap. Mask it with the previous bitmap, and draw your gradients to it.
  4. Now you can draw you gradient bitmap to the screen.

I think this accomplishes what you want:
gradient_mask

Example Program
import locale
try:    # wxPython
    import wx
except ImportError as err:
    print(str(err))
    print("Requires wxPython (www.wxpython.org)")
    print("\tpython -m pip install wxpython")
app = wx.App(False)
locale.setlocale(locale.LC_ALL, 'C')


class MainFrame(wx.Frame):
    def __init__(self, parent=None, title="", size=wx.DefaultSize):
        wx.Frame.__init__(self, parent=parent, title=title, size=size)
        self.Bind(wx.EVT_PAINT, self.OnPaint)

    def OnPaint(self, event):
        """Draw some stuff onto the frame client area."""
        # Draw onto a mask bitmap (black=masked, white=unmasked)
        mask_bitmap = wx.Bitmap(width=600, height=500, depth=1)
        dc = wx.MemoryDC()
        dc.SelectObject(mask_bitmap)
        # Unmask areas using white lines/splines.
        dc.SetPen(wx.WHITE_PEN)
        dc.DrawLine(0, 0, 100, 200)
        dc.SetPen(wx.Pen(wx.WHITE, width=5))
        dc.DrawSpline([(50, 0), (150, 100), (180, 400), (200, 100)])
        dc.SelectObject(wx.NullBitmap)

        # Create our gradient bitmap, masked with previous bitmap.
        bitmap = wx.Bitmap(width=600, height=500, depth=wx.BITMAP_SCREEN_DEPTH)
        bitmap.SetMask(wx.Mask(mask_bitmap))
        # Do some gradient fills.
        dc = wx.MemoryDC()
        dc.SelectObject(bitmap)
        r1  = wx.Rect(0, 0, 150, 150)
        dc.GradientFillLinear(r1, wx.Colour("#fff"), wx.Colour("#000"))
        r2  = wx.Rect(150, 150, 150, 150)
        dc.GradientFillConcentric(r2, wx.Colour("#fff"), wx.Colour("#000"), wx.Point(5, 5))
        dc.SelectObject(wx.NullBitmap)
        
        # Now paint our gradient bitmap to the window.
        dc = wx.PaintDC(self)
        dc.Clear()
        dc.DrawBitmap(bitmap, 0, 0, useMask=True)

# Instantiate and show frame and run event pump until user exits.
frame = MainFrame(parent=None, title="Draw Test", size=(600, 500))
frame.Show()
app.MainLoop()
2 Likes

Thank you @cbeytas