📄 bitmap.cpp
字号:
*destination++ = ((*data++) * a + 127) / 255 ;#else *destination++ = *data++ ; *destination++ = *data++ ; *destination++ = *data++ ;#endif } else { *destination++ = 0xFF ; *destination++ = *data++ ; *destination++ = *data++ ; *destination++ = *data++ ; } } } EndRawAccess() ; if ( image.HasMask() ) SetMask( new wxMask( *this , wxColour( image.GetMaskRed() , image.GetMaskGreen() , image.GetMaskBlue() ) ) ) ;}wxImage wxBitmap::ConvertToImage() const{ wxImage image; wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") ); // create an wxImage object int width = GetWidth(); int height = GetHeight(); image.Create( width, height ); unsigned char *data = image.GetData(); wxCHECK_MSG( data, wxNullImage, wxT("Could not allocate data for image") ); unsigned char* source = (unsigned char*) GetRawAccess() ; bool hasAlpha = false ; bool hasMask = false ; int maskBytesPerRow = 0 ; unsigned char *alpha = NULL ; unsigned char *mask = NULL ; if ( HasAlpha() ) hasAlpha = true ; if ( GetMask() ) { hasMask = true ; mask = (unsigned char*) GetMask()->GetRawAccess() ; maskBytesPerRow = GetMask()->GetBytesPerRow() ; } if ( hasAlpha ) { image.SetAlpha() ; alpha = image.GetAlpha() ; } int index = 0; // The following masking algorithm is the same as well in msw/gtk: // the colour used as transparent one in wxImage and the one it is // replaced with when it actually occurs in the bitmap static const int MASK_RED = 1; static const int MASK_GREEN = 2; static const int MASK_BLUE = 3; static const int MASK_BLUE_REPLACEMENT = 2; for (int yy = 0; yy < height; yy++ , mask += maskBytesPerRow ) { unsigned char * maskp = mask ; unsigned char a, r, g, b; long color; for (int xx = 0; xx < width; xx++) { color = *((long*) source) ;#ifdef WORDS_BIGENDIAN a = ((color&0xFF000000) >> 24) ; r = ((color&0x00FF0000) >> 16) ; g = ((color&0x0000FF00) >> 8) ; b = (color&0x000000FF);#else b = ((color&0xFF000000) >> 24) ; g = ((color&0x00FF0000) >> 16) ; r = ((color&0x0000FF00) >> 8) ; a = (color&0x000000FF);#endif if ( hasMask ) { if ( *maskp++ == 0xFF ) { r = MASK_RED ; g = MASK_GREEN ; b = MASK_BLUE ; } else if ( r == MASK_RED && g == MASK_GREEN && b == MASK_BLUE ) b = MASK_BLUE_REPLACEMENT ; maskp++ ; maskp++ ; maskp++ ; } else if ( hasAlpha ) *alpha++ = a ; data[index ] = r ; data[index + 1] = g ; data[index + 2] = b ; index += 3; source += 4 ; } } if ( hasMask ) image.SetMaskColour( MASK_RED, MASK_GREEN, MASK_BLUE ); return image;}#endif //wxUSE_IMAGEbool wxBitmap::SaveFile( const wxString& filename, wxBitmapType type, const wxPalette *palette ) const{ bool success = false; wxBitmapHandler *handler = FindHandler(type); if ( handler ) { success = handler->SaveFile(this, filename, type, palette); } else {#if wxUSE_IMAGE wxImage image = ConvertToImage(); success = image.SaveFile(filename, type);#else wxLogWarning(wxT("no bitmap handler for type %d defined."), type);#endif } return success;}bool wxBitmap::IsOk() const{ return (M_BITMAPDATA && M_BITMAPDATA->Ok());}int wxBitmap::GetHeight() const{ wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); return M_BITMAPDATA->GetHeight();}int wxBitmap::GetWidth() const{ wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); return M_BITMAPDATA->GetWidth() ;}int wxBitmap::GetDepth() const{ wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); return M_BITMAPDATA->GetDepth();}#if WXWIN_COMPATIBILITY_2_4int wxBitmap::GetQuality() const{ return 0;}void wxBitmap::SetQuality(int WXUNUSED(quality)){}#endifwxMask *wxBitmap::GetMask() const{ wxCHECK_MSG( Ok(), (wxMask *) NULL, wxT("invalid bitmap") ); return M_BITMAPDATA->m_bitmapMask;}bool wxBitmap::HasAlpha() const{ wxCHECK_MSG( Ok(), false , wxT("invalid bitmap") ); return M_BITMAPDATA->HasAlpha() ;}void wxBitmap::SetWidth(int w){ AllocExclusive(); M_BITMAPDATA->SetWidth(w);}void wxBitmap::SetHeight(int h){ AllocExclusive(); M_BITMAPDATA->SetHeight(h);}void wxBitmap::SetDepth(int d){ AllocExclusive(); M_BITMAPDATA->SetDepth(d);}void wxBitmap::SetOk(bool isOk){ AllocExclusive(); M_BITMAPDATA->SetOk(isOk);}#if wxUSE_PALETTEwxPalette *wxBitmap::GetPalette() const{ wxCHECK_MSG( Ok(), NULL, wxT("Invalid bitmap GetPalette()") ); return &M_BITMAPDATA->m_bitmapPalette;}void wxBitmap::SetPalette(const wxPalette& palette){ AllocExclusive(); M_BITMAPDATA->m_bitmapPalette = palette ;}#endif // wxUSE_PALETTEvoid wxBitmap::SetMask(wxMask *mask){ AllocExclusive(); // Remove existing mask if there is one. delete M_BITMAPDATA->m_bitmapMask; M_BITMAPDATA->m_bitmapMask = mask ;}WXHBITMAP wxBitmap::GetHBITMAP(WXHBITMAP* mask) const{ return WXHBITMAP(M_BITMAPDATA->GetHBITMAP((GWorldPtr*)mask));}// ----------------------------------------------------------------------------// wxMask// ----------------------------------------------------------------------------wxMask::wxMask(){ Init() ;}wxMask::wxMask(const wxMask &tocopy){ Init(); m_bytesPerRow = tocopy.m_bytesPerRow; m_width = tocopy.m_width; m_height = tocopy.m_height; size_t size = m_bytesPerRow * m_height; unsigned char* dest = (unsigned char*)m_memBuf.GetWriteBuf( size ); unsigned char* source = (unsigned char*)tocopy.m_memBuf.GetData(); for (size_t i=0; i<size; i++) { *dest++ = *source++; } m_memBuf.UngetWriteBuf( size ) ; RealizeNative() ;}// Construct a mask from a bitmap and a colour indicating// the transparent areawxMask::wxMask( const wxBitmap& bitmap, const wxColour& colour ){ Init() ; Create( bitmap, colour );}// Construct a mask from a mono bitmap (copies the bitmap).wxMask::wxMask( const wxBitmap& bitmap ){ Init() ; Create( bitmap );}// Construct a mask from a mono bitmap (copies the bitmap).wxMask::wxMask( const wxMemoryBuffer& data, int width , int height , int bytesPerRow ){ Init() ; Create( data, width , height , bytesPerRow );}wxMask::~wxMask(){#ifndef __LP64__ if ( m_maskBitmap ) { DisposeGWorld( (GWorldPtr)m_maskBitmap ) ; m_maskBitmap = NULL ; }#endif}void wxMask::Init(){ m_width = m_height = m_bytesPerRow = 0 ; m_maskBitmap = NULL ;}void *wxMask::GetRawAccess() const{ return m_memBuf.GetData() ;}// The default ColorTable for k8IndexedGrayPixelFormat in Intel appears to be broken, so we'll use an non-indexed// bitmap mask instead; in order to keep the code simple, the change applies to PowerPC implementations as wellvoid wxMask::RealizeNative(){#ifndef __LP64__ if ( m_maskBitmap ) { DisposeGWorld( (GWorldPtr)m_maskBitmap ) ; m_maskBitmap = NULL ; } Rect rect = { 0 , 0 , m_height , m_width } ; OSStatus err = NewGWorldFromPtr( (GWorldPtr*) &m_maskBitmap , k32ARGBPixelFormat , &rect , NULL , NULL , 0 , (char*) m_memBuf.GetData() , m_bytesPerRow ) ; verify_noerr( err ) ;#endif}// Create a mask from a mono bitmap (copies the bitmap).bool wxMask::Create(const wxMemoryBuffer& data,int width , int height , int bytesPerRow){ m_memBuf = data ; m_width = width ; m_height = height ; m_bytesPerRow = bytesPerRow ; wxASSERT( data.GetDataLen() == (size_t)(height * bytesPerRow) ) ; RealizeNative() ; return true ;}// Create a mask from a mono bitmap (copies the bitmap).bool wxMask::Create(const wxBitmap& bitmap){ m_width = bitmap.GetWidth() ; m_height = bitmap.GetHeight() ; m_bytesPerRow = ( m_width * 4 + 3 ) & 0xFFFFFFC ; size_t size = m_bytesPerRow * m_height ; unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ; wxASSERT( destdatabase != NULL ) ; memset( destdatabase , 0 , size ) ; unsigned char * srcdata = (unsigned char*) bitmap.GetRawAccess() ; for ( int y = 0 ; y < m_height ; ++y , destdatabase += m_bytesPerRow ) { unsigned char *destdata = destdatabase ; unsigned char r, g, b; for ( int x = 0 ; x < m_width ; ++x ) { srcdata++ ; r = *srcdata++ ; g = *srcdata++ ; b = *srcdata++ ; if ( ( r + g + b ) > 0x10 ) { *destdata++ = 0xFF ; *destdata++ = 0xFF ; *destdata++ = 0xFF ; *destdata++ = 0xFF ; } else { *destdata++ = 0x00 ; *destdata++ = 0x00 ; *destdata++ = 0x00 ; *destdata++ = 0x00 ; } } } m_memBuf.UngetWriteBuf( size ) ; RealizeNative() ; return true;}// Create a mask from a bitmap and a colour indicating// the transparent areabool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour){ m_width = bitmap.GetWidth() ; m_height = bitmap.GetHeight() ; m_bytesPerRow = ( m_width * 4 + 3 ) & 0xFFFFFFC ; size_t size = m_bytesPerRow * m_height ; unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ; wxASSERT( destdatabase != NULL ) ; memset( destdatabase , 0 , size ) ; unsigned char * srcdata = (unsigned char*) bitmap.GetRawAccess() ; for ( int y = 0 ; y < m_height ; ++y , destdatabase += m_bytesPerRow) { unsigned char *destdata = destdatabase ; unsigned char r, g, b; for ( int x = 0 ; x < m_width ; ++x ) { srcdata++ ; r = *srcdata++ ; g = *srcdata++ ; b = *srcdata++ ; if ( colour == wxColour( r , g , b ) ) { *destdata++ = 0xFF ; *destdata++ = 0xFF ; *destdata++ = 0xFF ; *destdata++ = 0xFF ; } else { *destdata++ = 0x00 ; *destdata++ = 0x00 ; *destdata++ = 0x00 ; *destdata++ = 0x00 ; } } } m_memBuf.UngetWriteBuf( size ) ; RealizeNative() ; return true;}WXHBITMAP wxMask::GetHBITMAP() const{ return m_maskBitmap ;}// ----------------------------------------------------------------------------// wxBitmapHandler// ----------------------------------------------------------------------------IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler, wxBitmapHandlerBase)// ----------------------------------------------------------------------------// Standard Handlers// ----------------------------------------------------------------------------class WXDLLEXPORT wxPICTResourceHandler: public wxBitmapHandler{ DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler)public: inline wxPICTResourceHandler() { SetName(wxT("Macintosh Pict resource")); SetExtension(wxEmptyString); SetType(wxBITMAP_TYPE_PICT_RESOURCE); }; virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags, int desiredWidth, int desiredHeight);};IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler, wxBitmapHandler)bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags, int desiredWidth, int desiredHeight){#if wxUSE_METAFILE Str255 theName ; wxMacStringToPascal( name , theName ) ; PicHandle thePict = (PicHandle ) GetNamedResource( 'PICT' , theName ) ; if ( thePict ) { wxMetafile mf ; mf.SetHMETAFILE( (WXHMETAFILE) thePict ) ; bitmap->Create( mf.GetWidth() , mf.GetHeight() ) ; wxMemoryDC dc ; dc.SelectObject( *bitmap ) ; mf.Play( &dc ) ; dc.SelectObject( wxNullBitmap ) ; return true ; }#endif return false ;}void wxBitmap::InitStandardHandlers(){ AddHandler( new wxPICTResourceHandler ) ; AddHandler( new wxICONResourceHandler ) ;}// ----------------------------------------------------------------------------// raw bitmap access support// ----------------------------------------------------------------------------void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp){ if ( !Ok() ) // no bitmap, no data (raw or otherwise) return NULL; data.m_width = GetWidth() ; data.m_height = GetHeight() ; data.m_stride = GetWidth() * 4 ; return BeginRawAccess() ;}void wxBitmap::UngetRawData(wxPixelDataBase& dataBase){ EndRawAccess() ;}void wxBitmap::UseAlpha(){ // remember that we are using alpha channel: // we'll need to create a proper mask in UngetRawData() M_BITMAPDATA->UseAlpha( true );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -