painting with alpha into dc 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
FireMail
Earned some good credits
Earned some good credits
Posts: 122
Joined: Fri Jun 10, 2005 8:34 am
Location: Austria
Contact:

painting with alpha into dc

Post by FireMail »

hi there,

i'm currently rendering graphics with cairo into a dc of a panel.
with cairo I can set rgba values for everything.

because I have multiple graphics I need to render, I create a wxMemoryDC connected with a bitmap:
wxMemoryDC pdc( *m_pkBmpPreview );
and draw into that MemoryDC

after rendering all my graphics I copy them together in my onpaint event:
dc->DrawBitmap( getPreviewBtmp(), Offset.x, Offset.y );

I floodfill the first memorydc with an alpha value of wxALPHA_TRANSPARENT, but the background is always white.
do you have any ideas how I can make the background of each own rendered preview bitmap to be transparent and not opaque white?

regards,
j
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GB/CS/CM/IT !d++ s+:-- a-- C++++$ UBL*++++$ P--- L++++$ !E-- !W+++$? !N-- !o K--? w++()$ !O M$ !V !PS? !PE? !Y? !PGP !t !5 !X R+++ tv++ !b? DI D++ G e+++ h++ r++ y+
------END GEEK CODE BLOCK------
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Post by doublemax »

When dealing with transparent pens/brushes you should use wxGraphicsContect/wxGCDC, but i'm not sure if it's possible to actually set the alpha buffer this way. You might have to set the alpha values yourself by using raw bitmap access.
Use the source, Luke!
FireMail
Earned some good credits
Earned some good credits
Posts: 122
Joined: Fri Jun 10, 2005 8:34 am
Location: Austria
Contact:

Post by FireMail »

it would be ok for me if i need to do raw bitmap access, if i can set the background to transparent.
do you have any references for me how to do that?
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GB/CS/CM/IT !d++ s+:-- a-- C++++$ UBL*++++$ P--- L++++$ !E-- !W+++$? !N-- !o K--? w++()$ !O M$ !V !PS? !PE? !Y? !PGP !t !5 !X R+++ tv++ !b? DI D++ G e+++ h++ r++ y+
------END GEEK CODE BLOCK------
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Post by doublemax »

pasted together from one of my projects:

Code: Select all

#include <wx/rawbmp.h>
static void rawBmpFill(wxBitmap *bmp, wxColor col)
{
  wxAlphaPixelData bmdata(*bmp);
  if(bmdata==NULL) {
    wxLogDebug(wxT("rawBmpFill() failed"));
    return;
  }

  bmdata.UseAlpha();
  wxAlphaPixelData::Iterator dst(bmdata);

  // rgb-values need to be pre-multiplied with alpha
  unsigned char a=col.Alpha();
  unsigned char r=col.Red()*a/255;
  unsigned char g=col.Green()*a/255;
  unsigned char b=col.Blue()*a/255;

  for(int y=0; y<bmp->GetHeight(); y++) {
    dst.MoveTo(bmdata, 0, y);
    for(int x=0; x<bmp->GetWidth(); x++) {
      dst.Red()=r;
      dst.Green()=g;
      dst.Blue()=b;
      dst.Alpha()=a;
      dst++;
    }
  }
}
Use the source, Luke!
turova
Experienced Solver
Experienced Solver
Posts: 54
Joined: Wed Jan 16, 2008 3:49 pm

Post by turova »

Maybe I don't understand what you want to do, but maybe you could get away with using the last argument of

Code: Select all

void DrawBitmap(const wxBitmap& bitmap, wxCoord x, wxCoord y, bool transparent)
So I'm guessing you should be able to do something like this:

Code: Select all

wxMemoryDC pdc( *m_pkBmpPreview ); 
//clear background to a color you don't use, for example *wxWHITE
//draw whatever you want
//close pdc
m_pkBmpPreview->SetMask(new wxMask(*m_pkBmpPreview,*wxWHITE));//Set mask to use the background color

//...then, when rendering:
dc->DrawBitmap( getPreviewBtmp(), Offset.x, Offset.y, 1 );//Draw using the transparency mask
FireMail
Earned some good credits
Earned some good credits
Posts: 122
Joined: Fri Jun 10, 2005 8:34 am
Location: Austria
Contact:

Post by FireMail »

turova wrote:Maybe I don't understand what you want to do, but maybe you could get away with using the last argument of

Code: Select all

void DrawBitmap(const wxBitmap& bitmap, wxCoord x, wxCoord y, bool transparent)
So I'm guessing you should be able to do something like this:

Code: Select all

wxMemoryDC pdc( *m_pkBmpPreview ); 
//clear background to a color you don't use, for example *wxWHITE
//draw whatever you want
//close pdc
m_pkBmpPreview->SetMask(new wxMask(*m_pkBmpPreview,*wxWHITE));//Set mask to use the background color

//...then, when rendering:
dc->DrawBitmap( getPreviewBtmp(), Offset.x, Offset.y, 1 );//Draw using the transparency mask
this really looks good to me, but when implementing it, it only drops me assert errors: !bitmap.GetSelectedInto() failed in wxMask::Create(): bitmap can't be selected in another DC.

i dont get where the error could be or what the message means.
here is the code i used

Code: Select all

	m_pkBmpPreview = new wxBitmap( GetMaxX()*fScalefactorX, GetMaxY()*fScalefactorY );
	wxMemoryDC pdc( *m_pkBmpPreview );
...
	// Clear background
	cairo_set_source_rgba( cr, 1, 0, 0, 1 );
	cairo_paint( cr );
...
	m_pkBmpPreview->SetMask( new wxMask(*m_pkBmpPreview,wxColour(255,0,0) ) );
...
so there shouldn't be anything wrong?!
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GB/CS/CM/IT !d++ s+:-- a-- C++++$ UBL*++++$ P--- L++++$ !E-- !W+++$? !N-- !o K--? w++()$ !O M$ !V !PS? !PE? !Y? !PGP !t !5 !X R+++ tv++ !b? DI D++ G e+++ h++ r++ y+
------END GEEK CODE BLOCK------
FireMail
Earned some good credits
Earned some good credits
Posts: 122
Joined: Fri Jun 10, 2005 8:34 am
Location: Austria
Contact:

Post by FireMail »

thanks i fixed it.
had to change the creation of the DC to be dynamic and not static and then to delete the dc bevore adding the mask.

thank you both for your ideas, works great, looks good :)
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GB/CS/CM/IT !d++ s+:-- a-- C++++$ UBL*++++$ P--- L++++$ !E-- !W+++$? !N-- !o K--? w++()$ !O M$ !V !PS? !PE? !Y? !PGP !t !5 !X R+++ tv++ !b? DI D++ G e+++ h++ r++ y+
------END GEEK CODE BLOCK------
Post Reply