Drawing With 'Layers'

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Drawing With 'Layers'

Post by Everydaydiesel »

Hello,

I am trying to draw in 'layers' but the code is not exactly doing what I intended.
Here is the input to the program (always png/bmp)
Input.png
Input.png (7.26 KiB) Viewed 1559 times
What I want it to do is draw the line BEHIND the text. I think the way I do this is with the following steps (I could be wrong)
1. Load the image (always a white background / black(dark) text)
2. Make the background transparent
3. Draw the background (white)
4. Draw the line
5. Draw the text

Here is the code but the line is not under the text (it is drawn on top)

Code: Select all

    wxBitmap bmp(463, 105, 32);
    wxMask *pmask = new wxMask(bmp, wxColour(255, 255, 255));
    bmp.SetMask(pmask);
    bmp.LoadFile("Input.png"); // , wxBITMAP_PNG());
    wxMemoryDC memDC(bmp);
    memDC.SetBackground(*wxTRANSPARENT_BRUSH);
    memDC.SetBackgroundMode(wxTRANSPARENT);
    memDC.SetPen(*wxRED_PEN);
    memDC.DrawLine(25, 61, 427, 61);  // for testing purposes
    memDC.SelectObject( wxNullBitmap );
    bmp.SaveFile("TestOutput.png", wxBITMAP_TYPE_PNG);
  
Thanks in advance for any help you can give

Actual Output:
ActualOutput.png
ActualOutput.png (7.25 KiB) Viewed 1559 times

Target Output:
TargetOutput.png
TargetOutput.png (7.35 KiB) Viewed 1559 times
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Re: Drawing With 'Layers'

Post by Everydaydiesel »

Here is the enlarged version of the ouput


Actual Output:
ActualOutputEnlarged.png
ActualOutputEnlarged.png (4.25 KiB) Viewed 1554 times

Target Output:
TargetOutputEnlarged.png
TargetOutputEnlarged.png (4.19 KiB) Viewed 1554 times
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Drawing With 'Layers'

Post by doublemax »

Create a wxMask based on the background color. Call wxBitmap::SetMask(), then draw.
Use the source, Luke!
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Re: Drawing With 'Layers'

Post by Everydaydiesel »

Thank you for the reply. I thought I was doing that? Maybe LoadFile clears the mask out?

Code: Select all

    wxBitmap bmp(463, 105, 32);
    wxMask *pmask = new wxMask(bmp, wxColour(255, 255, 255));
    bmp.SetMask(pmask);
    bmp.LoadFile("Input.png"); 

edit: I tried the DrawBitmap function after DrawLine but it still did not work.

Code: Select all

    wxBitmap bmp(463, 105, 32);
    wxMask *pmask = new wxMask(bmp, wxColour(255, 255, 255));
    bmp.SetMask(pmask);
    bmp.LoadFile("Input.png");
    wxMemoryDC memDC(bmp);
    memDC.SetBackground(*wxTRANSPARENT_BRUSH);
    memDC.SetBackgroundMode(wxTRANSPARENT);
    wxColour col;
    memDC.SetPen(*wxRED_PEN);
    memDC.DrawLine(25, 61, 427, 61);
    memDC.DrawBitmap(bmp, 0, 0, true);
    memDC.SelectObject( wxNullBitmap );
    bmp.SaveFile("TestOutput.png", wxBITMAP_TYPE_PNG);
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Drawing With 'Layers'

Post by doublemax »

Creating and setting the mask needs to happen after loading. (The mask is created from the image data).
Use the source, Luke!
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Re: Drawing With 'Layers'

Post by Everydaydiesel »

Thanks. I think I am getting closer. This code creates this but it is not drawing the red line for some reason. (the background is transparent)
TestOutput.png
TestOutput.png (7.46 KiB) Viewed 1514 times

Code: Select all

    wxBitmap bmp(463, 105, 32);
    bmp.LoadFile("Input.png");

    wxMemoryDC memDC(bmp);
    memDC.SetBackground(*wxTRANSPARENT_BRUSH);
    memDC.SetBackgroundMode(wxTRANSPARENT);
    wxMask *pmask = new wxMask(bmp, wxColour(255, 255, 255));
    bmp.SetMask(pmask);
    
    memDC.SetBackground(*wxWHITE_BRUSH);  // this isnt working
    memDC.SetPen(*wxRED_PEN);
    memDC.DrawLine(25, 61, 427, 61);
    memDC.DrawBitmap(bmp, 0, 0, true);
    memDC.SelectObject( wxNullBitmap );
    bmp.SaveFile("TestOutput.png", wxBITMAP_TYPE_PNG);
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Drawing With 'Layers'

Post by doublemax »

Try this:

Code: Select all

    wxBitmap bmp("Input.png", wxBITMAP_TYPE_ANY);

    wxMask *pmask = new wxMask(bmp, wxColour(255, 255, 255));
    bmp.SetMask(pmask);

    wxMemoryDC memDC(bmp);
    memDC.SetPen(*wxRED_PEN);
    memDC.DrawLine(25, 61, 427, 61);
    memDC.SelectObject( wxNullBitmap );
    
    bmp.SaveFile("TestOutput.png", wxBITMAP_TYPE_PNG);
Use the source, Luke!
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Re: Drawing With 'Layers'

Post by Everydaydiesel »

I tried that code but the line is still on top of the text instead of underneath
OutputEnlarged.png
OutputEnlarged.png (4.07 KiB) Viewed 1504 times
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Drawing With 'Layers'

Post by doublemax »

Ok. After studying the documentation, it seems that the mask is only used when reading from the bitmap, not writing into it. This requires a new strategy :)

Tested:

Code: Select all

wxBitmap bmp("d:\\Input.png", wxBITMAP_TYPE_ANY);

wxMask *pmask = new wxMask(bmp, *wxWHITE);
bmp.SetMask(pmask);

wxBitmap target(bmp.GetWidth(), bmp.GetHeight(), 24 );

wxMemoryDC memDC(target);
memDC.SetBackground(*wxWHITE);
memDC.Clear();

memDC.SetPen(*wxRED_PEN);
memDC.DrawLine(25, 61, 427, 61);

memDC.DrawBitmap( bmp, 0, 0, true );

memDC.SelectObject( wxNullBitmap );

target.SaveFile("d:\\TestOutput.png", wxBITMAP_TYPE_PNG);
This draws the red line first, then draws the masked bitmap on top. The result is not perfect, because of the grey pixels which get not masked.
Use the source, Luke!
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Re: Drawing With 'Layers'

Post by Everydaydiesel »

Does it draw a line on yours? When I try it on mine it doesnt draw the red line.

build 2017-09-30, 18:21:54 wx3.0.3 (Linux, unicode) 64 bit
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Drawing With 'Layers'

Post by doublemax »

Yes, here's my result:
TestOutput.png
TestOutput.png (6.58 KiB) Viewed 1493 times
I tested under Windows though.
Use the source, Luke!
Post Reply