Opened 3 months ago

Closed 3 months ago

#18493 closed defect (invalid)

wxBitmap with partial transparency drawn improperly on wxMemoryDC

Reported by: awi Owned by:
Priority: normal Milestone:
Component: wxOSX Version: dev-latest
Keywords: Cc:
Blocked By: Blocking:
Patch: no

Description

When 32bpp ARGB wxBitmap with partial transparency is drawn on wxMemoryDC, its alpha channel values are apparently not taken into account and bitmap is drawn if it has no transparency channel at all.
wxBitmaps with alpha values containing only 0 or 255 values are drawn properly.
This issue can be observed (on OS X 10.11) with following patch applied to the minimal sample:

  • samples/minimal/minimal.cpp

    diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
    a b bool MyApp::OnInit() 
    139139// ----------------------------------------------------------------------------
    140140// main frame
    141141// ----------------------------------------------------------------------------
     142#include "wx/rawbmp.h"
    142143
    143144// frame constructor
    144145MyFrame::MyFrame(const wxString& title)
    MyFrame::MyFrame(const wxString& title) 
    178179    CreateStatusBar(2);
    179180    SetStatusText("Welcome to wxWidgets!");
    180181#endif // wxUSE_STATUSBAR
     182    int w = 64;
     183    int h = 64;
     184
     185    wxBitmap bmpAlpha(w, h, 32);
     186    bmpAlpha.UseAlpha();
     187    {
     188        wxMemoryDC dc(bmpAlpha);
     189        dc.SetBackground(*wxGREEN_BRUSH);
     190        dc.Clear();
     191    }
     192    {
     193        wxAlphaPixelData data(bmpAlpha);
     194        wxAlphaPixelData::Iterator p(data);
     195        for ( int y = 0; y < h; y++ )
     196        {
     197            wxAlphaPixelData::Iterator rowStart = p;
     198            for ( int x = 0; x < w; x++, ++p )
     199            {
     200                p.Alpha() = x < w / 2 ? 255 : 92;
     201            }
     202            p = rowStart;
     203            p.OffsetY(data, 1);
     204        }
     205    }
     206    wxASSERT(bmpAlpha.HasAlpha());
     207    wxASSERT(!bmpAlpha.GetMask());
     208
     209    wxBitmap bmp(w, h, 24);
     210    {
     211        wxMemoryDC dc(bmp);
     212        dc.SetPen(*wxBLUE_PEN);
     213        dc.SetBrush(*wxBLUE_BRUSH);
     214        dc.DrawRectangle(0, 0, w / 2, h);
     215        dc.SetPen(*wxRED_PEN);
     216        dc.SetBrush(*wxRED_BRUSH);
     217        dc.DrawRectangle(w / 2, 0, w / 2, h);
     218    }
     219    wxASSERT(!bmp.HasAlpha());
     220    wxASSERT(!bmp.GetMask());
     221
     222    wxBitmap bmpSample(sample_xpm);
     223    wxASSERT(bmpSample.HasAlpha());
     224    wxASSERT(!bmpSample.GetMask());
     225
     226    wxBitmap bmpOut(300, 100, 24);
     227    {
     228        wxMemoryDC dc(bmpOut);
     229        dc.SetBackground(*wxGREY_BRUSH);
     230        dc.Clear();
     231
     232        dc.DrawBitmap(bmpSample, wxPoint(20, 20));
     233        dc.DrawBitmap(bmpAlpha, wxPoint(110, 20));
     234        dc.DrawBitmap(bmp, wxPoint(200, 20));
     235    }
     236
     237    wxPanel* p = new wxPanel(this);
     238
     239    new wxStaticBitmap(p, wxID_ANY, bmpSample, wxPoint(20, 20));
     240    new wxStaticBitmap(p, wxID_ANY, bmpAlpha, wxPoint(110, 20));
     241    new wxStaticBitmap(p, wxID_ANY, bmp, wxPoint(200, 20));
     242
     243    new wxStaticBitmap(p, wxID_ANY, bmpOut, wxPoint(0, 110));
    181244}

The result looks like this:
Drawing ARGB and RGB bitmaps

Attachments (1)

draw_bitmap_alpha.png download (8.8 KB) - added by awi 3 months ago.
Drawing ARGB and RGB bitmaps

Download all attachments as: .zip

Change History (2)

Changed 3 months ago by awi

Drawing ARGB and RGB bitmaps

comment:1 Changed 3 months ago by awi

  • Resolution set to invalid
  • Status changed from new to closed

Sorry for raising a false alarm. I've forgot that RGB data in the bitmaps with transparency should be premultiplied.

Note: See TracTickets for help on using tickets.