Drawing transparent bitmap on panel Topic is solved

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
vinayakgarg
Earned a small fee
Earned a small fee
Posts: 17
Joined: Tue Dec 06, 2011 9:22 am
Location: Delhi, India
Contact:

Drawing transparent bitmap on panel

Post by vinayakgarg »

Hi,
I want to draw a rectangle with rounded corners on a wxPanel.
As shown below, i am unable to get it transparent. The white area should be transparent.
sc3.png
sc3.png (442 Bytes) Viewed 9293 times
The grey area is a bitmap and below it there is a wxPanel background. My code for drawing bitmap (wxBitmap) is

Code: Select all

wxMemoryDC temp;
bitmap.Create(kWidth, kHeight);
temp.SelectObject(bitmap);
temp.SetBackground(*wxWHITE_BRUSH);
temp.Clear();
temp.SetPen(wxPen(wxColor(80, 80, 80), 1));
temp.SetBrush(*wxTRANSPARENT_BRUSH);
temp.DrawRectangle(0, 0, kWidth, kHeight);
temp.SetBrush(wxBrush(backgroundColor));
temp.DrawRoundedRectangle(0, 0, kWidth, kHeight, kRadius);
And for bliting (for refresh) my code is

Code: Select all

void draw(wxDC& dc, wxPoint mousePosition)
{
    wxMemoryDC temp;
    temp.SelectObject(bitmap);
    dc.Blit(wxPoint(kLeft, kTop), temp.GetSize(), &temp, wxPoint(0, 0), wxCOPY, true);
}
But the output is as shown above. What am I doing wrong?
Thanks
Vinayak
dave9343
Experienced Solver
Experienced Solver
Posts: 58
Joined: Sun Jun 19, 2011 11:38 pm

Re: Drawing transparent bitmap on panel

Post by dave9343 »

if the png does not contain transparency information then it won't display as transparent - the color white won't show as transparent.
vinayakgarg
Earned a small fee
Earned a small fee
Posts: 17
Joined: Tue Dec 06, 2011 9:22 am
Location: Delhi, India
Contact:

Re: Drawing transparent bitmap on panel

Post by vinayakgarg »

dave9343 wrote:if the png does not contain transparency information then it won't display as transparent - the color white won't show as transparent.
i am not loading a PNG from disk. i am just creating a bitmap using the first piece of code. I have used wxTransparent_brush for painting the background of bitmap.
Thanks
Vinayak
dave9343
Experienced Solver
Experienced Solver
Posts: 58
Joined: Sun Jun 19, 2011 11:38 pm

Re: Drawing transparent bitmap on panel

Post by dave9343 »

I am not sure, however

temp.SetBackground(*wxWHITE_BRUSH);
temp.Clear();

these calls would set the color to white, then you are trying to use the transparent brush to draw into the alpha channel ... it might actually not draw anything instead
for situations when you don't want the brush to be visible, so all that would show would be the background?

Maybe you should get access to the buffer and set the pixels alpha values to zero (for non-opaque).
dave9343
Experienced Solver
Experienced Solver
Posts: 58
Joined: Sun Jun 19, 2011 11:38 pm

Re: Drawing transparent bitmap on panel

Post by dave9343 »

The "image" sample has some code that creates an alpha bitmap, in image.cpp

Code: Select all


        // First, clear the whole bitmap by making it alpha
        {
            wxAlphaPixelData data( m_alphaBitmap, wxPoint(0,0), wxSize(SIZE, SIZE) );
            if ( !data )
            {
                wxLogError(wxT("Failed to gain raw access to bitmap data"));
                return;
            }
            wxAlphaPixelData::Iterator p(data);
            for ( int y = 0; y < SIZE; ++y )
            {
                wxAlphaPixelData::Iterator rowStart = p;
                for ( int x = 0; x < SIZE; ++x )
                {
                    p.Alpha() = 0;
                    ++p; // same as p.OffsetX(1)
                }
                p = rowStart;
                p.OffsetY(data, 1);
            }

//etc
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Drawing transparent bitmap on panel

Post by doublemax »

The problem is that the "standard" wxDC functions don't handle transparency too well. And drawing with a transparent brush is like a no-operation, it does nothing.

You have to use wxGraphicsContext or wxGCDC for this.

This sample code creates a transparent bitmap with a red rectangle in the middle:

Code: Select all

#include "wx/dcgraph.h"

::wxInitAllImageHandlers();
wxBitmap bmp( 64, 64, 32 );
bmp.UseAlpha();

wxMemoryDC memDC( bmp );
wxGCDC dc( memDC );

dc.SetBackground( *wxTRANSPARENT_BRUSH );
dc.Clear();

dc.SetBrush( *wxRED_BRUSH );
dc.SetPen( *wxTRANSPARENT_PEN );
dc.DrawRectangle( 10, 10, 44, 44 );

memDC.SelectObject( wxNullBitmap );
bmp.SaveFile( wxT( "c:\\test.png" ), wxBITMAP_TYPE_PNG );
if you're using this under Windows, you need to add "gdiplus.lib" to the linker input files. This library is part of the Windows platform SDK, not part of wxWidgets.
Use the source, Luke!
vinayakgarg
Earned a small fee
Earned a small fee
Posts: 17
Joined: Tue Dec 06, 2011 9:22 am
Location: Delhi, India
Contact:

Re: Drawing transparent bitmap on panel

Post by vinayakgarg »

@doublemax : You hit right on the target!! Thanks so much.
sc4.png
sc4.png (487 Bytes) Viewed 9249 times
dave9343 wrote:I am not sure, however

temp.SetBackground(*wxWHITE_BRUSH);
temp.Clear();

these calls would set the color to white, then you are trying to use the transparent brush to draw into the alpha channel ... it might actually not draw anything instead
for situations when you don't want the brush to be visible, so all that would show would be the background?

Maybe you should get access to the buffer and set the pixels alpha values to zero (for non-opaque).
Your have a valid point there. Made me think in the right direction.
Everydaydiesel
Earned some good credits
Earned some good credits
Posts: 125
Joined: Wed Oct 28, 2015 9:48 pm

Re: Drawing transparent bitmap on panel

Post by Everydaydiesel »

doublemax wrote: Sat Dec 17, 2011 12:11 pm The problem is that the "standard" wxDC functions don't handle transparency too well. And drawing with a transparent brush is like a no-operation, it does nothing.

You have to use wxGraphicsContext or wxGCDC for this.

This sample code creates a transparent bitmap with a red rectangle in the middle:

Code: Select all

#include "wx/dcgraph.h"

::wxInitAllImageHandlers();
wxBitmap bmp( 64, 64, 32 );
bmp.UseAlpha();

wxMemoryDC memDC( bmp );
wxGCDC dc( memDC );

dc.SetBackground( *wxTRANSPARENT_BRUSH );
dc.Clear();

dc.SetBrush( *wxRED_BRUSH );
dc.SetPen( *wxTRANSPARENT_PEN );
dc.DrawRectangle( 10, 10, 44, 44 );

memDC.SelectObject( wxNullBitmap );
bmp.SaveFile( wxT( "c:\\test.png" ), wxBITMAP_TYPE_PNG );
if you're using this under Windows, you need to add "gdiplus.lib" to the linker input files. This library is part of the Windows platform SDK, not part of wxWidgets.
Sorry to bring up an old thread, but 8 years later, I am trying to do a very similar thing.
test.png
test.png (486 Bytes) Viewed 2964 times
The code above produces the image attached. Please note that wxBitmap does not have a UseAlpha() process anymore and I suspect this is the problem.



What I need to do is take in an image with a white background (making the white transparent)
Here is a sample
test_sample.png
test_sample.png (6.29 KiB) Viewed 2962 times
New Pagodi
Super wx Problem Solver
Super wx Problem Solver
Posts: 466
Joined: Tue Jun 20, 2006 6:47 pm
Contact:

Re: Drawing transparent bitmap on panel

Post by New Pagodi »

That's pretty much the classical job for a mask. With wxWidgets, you create a mask like this (assuming m_bmp is a wxBitmap member of the MyFrame class):

Code: Select all

MyFrame::MyFrame(...):wxFrame(...)
{
	...
    ::wxInitAllImageHandlers();
    Bind(wxEVT_PAINT,&MyFrame::OnPaint,this);

    m_bmp = wxBitmap("test_sample.png",wxBITMAP_TYPE_PNG );
    m_bmp.SetMask(new wxMask(m_bmp,*wxWHITE));

}

void MyFrame::OnPaint(wxPaintEvent& ev)
{
    wxPaintDC dc(this);
    dc.DrawBitmap(m_bmp,0,0,true);
}
Note that because of the antiialiasing in that particular png, it doesn't seem to draw well with a mask
g.png
g.png (6.12 KiB) Viewed 2953 times
You probably want to use a different png or simply use the wxDC functions like DrawText, DrawCircle, DrawRectangle instead of drawing a bitmap.
Post Reply