Surface8u convertGdiplusBitmap( Gdiplus::Bitmap &bitmap ) { Gdiplus::BitmapData bitmapData; Gdiplus::Rect rect( 0, 0, bitmap.GetWidth(), bitmap.GetHeight() ); Gdiplus::PixelFormat requestedFormat = bitmap.GetPixelFormat(); SurfaceChannelOrder sco; bool premult; gdiplusPixelFormatToSurfaceChannelOrder( requestedFormat, &sco, &premult ); if( sco == SurfaceChannelOrder::UNSPECIFIED ) { UINT flags = bitmap.GetFlags(); sco = ( flags & Gdiplus::ImageFlagsHasAlpha ) ? SurfaceChannelOrder::BGRA : SurfaceChannelOrder::BGR; requestedFormat = ( flags & Gdiplus::ImageFlagsHasAlpha ) ? PixelFormat32bppARGB : PixelFormat24bppRGB; } bitmap.LockBits( &rect, Gdiplus::ImageLockModeRead, requestedFormat, &bitmapData ); Surface8u result( bitmap.GetWidth(), bitmap.GetHeight(), sco.hasAlpha(), sco ); const uint8_t *srcDataBase = (uint8_t*)bitmapData.Scan0; int32_t width = bitmap.GetWidth(); for( uint32_t y = 0; y < bitmap.GetHeight(); ++y ) { memcpy( result.getData( Vec2i( 0, y ) ), srcDataBase + y * bitmapData.Stride, width * result.getPixelInc() ); } bitmap.UnlockBits( &bitmapData ); return result; }
Bitmap CanvasGdiplus::ExtractBitmap() const { DCHECK(!mem_bitmap_.IsNull()); // 生成一个位图, 绘制画布内容到其中并返回. Gdiplus::Bitmap* bitmap = mem_bitmap_.GetNativeBitmap(); Gdiplus::Rect rc_bitmap(0, 0, bitmap->GetWidth(), bitmap->GetHeight()); return Bitmap(bitmap->Clone(rc_bitmap, bitmap->GetPixelFormat())); }
void* BaseManager::loadImage(int& _width, int& _height, MyGUI::PixelFormat& _format, const std::string& _filename) { std::string fullname = MyGUI::OpenGL3DataManager::getInstance().getDataPath(_filename); void* result = 0; Gdiplus::Bitmap* image = Gdiplus::Bitmap::FromFile(MyGUI::UString(fullname).asWStr_c_str()); if (image) { _width = image->GetWidth(); _height = image->GetHeight(); Gdiplus::PixelFormat format = image->GetPixelFormat(); if (format == PixelFormat24bppRGB) _format = MyGUI::PixelFormat::R8G8B8; else if (format == PixelFormat32bppARGB) _format = MyGUI::PixelFormat::R8G8B8A8; else _format = MyGUI::PixelFormat::Unknow; if (_format != MyGUI::PixelFormat::Unknow) { Gdiplus::Rect rect(0, 0, _width, _height); Gdiplus::BitmapData out_data; image->LockBits(&rect, Gdiplus::ImageLockModeRead, format, &out_data); size_t size = out_data.Height * out_data.Stride; result = new unsigned char[size]; convertRawData(&out_data, result, size, _format); image->UnlockBits(&out_data); } delete image; } return result; }
HRESULT BitmapUtil::MyCreateFromGdiplusBitmap( Gdiplus::Bitmap& bmSrc ) throw() { Gdiplus::PixelFormat eSrcPixelFormat = bmSrc.GetPixelFormat(); UINT nBPP = 32; DWORD dwFlags = 0; Gdiplus::PixelFormat eDestPixelFormat = PixelFormat32bppRGB; if( eSrcPixelFormat&PixelFormatGDI ) { nBPP = Gdiplus::GetPixelFormatSize( eSrcPixelFormat ); eDestPixelFormat = eSrcPixelFormat; } if( Gdiplus::IsAlphaPixelFormat( eSrcPixelFormat ) ) { nBPP = 32; dwFlags |= createAlphaChannel; eDestPixelFormat = PixelFormat32bppARGB; } BOOL bSuccess = Create( bmSrc.GetWidth(), bmSrc.GetHeight(), nBPP, dwFlags ); if( !bSuccess ) { return( E_FAIL ); } Gdiplus::ColorPalette* pPalette = NULL; if( Gdiplus::IsIndexedPixelFormat( eSrcPixelFormat ) ) { UINT nPaletteSize = bmSrc.GetPaletteSize(); pPalette = static_cast< Gdiplus::ColorPalette* >( _alloca( nPaletteSize ) ); bmSrc.GetPalette( pPalette, nPaletteSize ); RGBQUAD argbPalette[256]; ATLASSERT( (pPalette->Count > 0) && (pPalette->Count <= 256) ); for( UINT iColor = 0; iColor < pPalette->Count; iColor++ ) { Gdiplus::ARGB color = pPalette->Entries[iColor]; argbPalette[iColor].rgbRed = BYTE( color>>RED_SHIFT ); argbPalette[iColor].rgbGreen = BYTE( color>>GREEN_SHIFT ); argbPalette[iColor].rgbBlue = BYTE( color>>BLUE_SHIFT ); argbPalette[iColor].rgbReserved = 0; } SetColorTable( 0, pPalette->Count, argbPalette ); } if( eDestPixelFormat == eSrcPixelFormat ) { // The pixel formats are identical, so just memcpy the rows. Gdiplus::BitmapData data; Gdiplus::Rect rect( 0, 0, GetWidth(), GetHeight() ); bmSrc.LockBits( &rect, Gdiplus::ImageLockModeRead, eSrcPixelFormat, &data ); UINT nBytesPerRow = AtlAlignUp( nBPP*GetWidth(), 8 )/8; BYTE* pbDestRow = static_cast< BYTE* >( GetBits() ); BYTE* pbSrcRow = static_cast< BYTE* >( data.Scan0 ); for( int y = 0; y < GetHeight(); y++ ) { memcpy( pbDestRow, pbSrcRow, nBytesPerRow ); pbDestRow += GetPitch(); pbSrcRow += data.Stride; } bmSrc.UnlockBits( &data ); } else { // Let GDI+ work its magic Gdiplus::Bitmap bmDest( GetWidth(), GetHeight(), GetPitch(), eDestPixelFormat, static_cast< BYTE* >( GetBits() ) ); Gdiplus::Graphics gDest( &bmDest ); gDest.DrawImage( &bmSrc, 0, 0 ); } return( S_OK ); }
bool CPicture::LoadTextureOverGDI(const std::string& fileName, int maxWidth, int maxHeight) { CleanUp(); int filenameSize; LPWSTR filenameWSTR; Gdiplus::Bitmap* pThumbnail = NULL; Gdiplus::PixelFormat pixelFormat; // File filenameSize = MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED, fileName.c_str(), -1, 0, 0); filenameWSTR = (LPWSTR) malloc(filenameSize * sizeof(LPWSTR)); MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED, fileName.c_str(), -1, filenameWSTR, filenameSize); // load with gdi++ Gdiplus::Bitmap imageBitmap(filenameWSTR); free (filenameWSTR); if ((maxWidth != -1) && (maxHeight != -1)) { if (maxWidth == -1) maxWidth = imageBitmap.GetWidth(); if (maxHeight == -1) maxHeight = imageBitmap.GetHeight(); float iWidthRelation = (float) imageBitmap.GetWidth() / maxWidth; float iHeightRelation = (float) imageBitmap.GetHeight() / maxHeight; if (imageBitmap.GetWidth() > imageBitmap.GetHeight()) { maxHeight = (long) (imageBitmap.GetHeight() / iWidthRelation); } else { maxWidth = (long) (imageBitmap.GetWidth() / iHeightRelation); } if ((maxWidth <= 128) && (maxHeight <= 128)) { pThumbnail = (Gdiplus::Bitmap*) imageBitmap.GetThumbnailImage(maxWidth, maxHeight, NULL, NULL); pixelFormat = pThumbnail->GetPixelFormat(); } else { pixelFormat = imageBitmap.GetPixelFormat(); } } else { maxWidth = imageBitmap.GetWidth(); maxHeight = imageBitmap.GetHeight(); pixelFormat = imageBitmap.GetPixelFormat(); } if (!this->CreateEmptyPixelFormat(maxWidth, maxHeight, pixelFormat)) { SallyAPI::System::CLogger* logger = SallyAPI::Core::CGame::GetLogger(); logger->Error("CPicture::LoadTextureOverGDI() CreateEmptyPixelFormat failed"); SafeDelete(pThumbnail); return false; } IDirect3DSurface9* surface = NULL; SallyAPI::Core::CTexture* texture = this->GetTexture(); if (texture == NULL) { SallyAPI::System::CLogger* logger = SallyAPI::Core::CGame::GetLogger(); logger->Error("CPicture::LoadTextureOverGDI() CTexture->GetTexture failed"); SafeDelete(pThumbnail); return false; } LPDIRECT3DTEXTURE9 d3dTexture = texture->GetTexture(); if (d3dTexture == NULL) { SallyAPI::System::CLogger* logger = SallyAPI::Core::CGame::GetLogger(); logger->Error("CPicture::LoadTextureOverGDI() LPDIRECT3DTEXTURE9->GetTexture failed"); SafeDelete(pThumbnail); return false; } D3DSURFACE_DESC pDesc; d3dTexture->GetLevelDesc(0, &pDesc); d3dTexture->GetSurfaceLevel(0, &surface); HDC hdc; surface->GetDC(&hdc); if (pThumbnail == NULL) { Gdiplus::Graphics graphics(hdc); graphics.DrawImage(&imageBitmap, 0, 0, pDesc.Width, pDesc.Height); } else { Gdiplus::Graphics graphics(hdc); graphics.DrawImage(pThumbnail, 0, 0, pDesc.Width, pDesc.Height); /* Gdiplus::Graphics graphics(pThumbnail); HDC dcThumbnail = graphics.GetHDC(); ::BitBlt(hdc, 0, 0, pDesc.Width, pDesc.Height, dcThumbnail, 0, 0, pThumbnail->GetWidth(), pThumbnail->GetHeight(), SRCCOPY); graphics.ReleaseHDC(dcThumbnail); */ } surface->ReleaseDC(hdc); surface->Release(); SafeDelete(pThumbnail); return true; }