// cf. http://stackoverflow.com/questions/4598872/creating-hbitmap-from-memory-buffer/4616394#4616394 Bitmap *BitmapFromData(const char *data, size_t len) { ImgFormat format = GfxFormatFromData(data, len); if (Img_TGA == format) return tga::ImageFromData(data, len); if (Img_WebP == format) return webp::ImageFromData(data, len); if (Img_JP2 == format) return fitz::ImageFromData(data, len); if (Img_JPEG == format && JpegUsesArithmeticCoding(data, len)) return fitz::ImageFromData(data, len); ScopedComPtr<IStream> stream(CreateStreamFromData(data, len)); if (!stream) return NULL; if (Img_JXR == format) return WICDecodeImageFromStream(stream); Bitmap *bmp = Bitmap::FromStream(stream); if (bmp && bmp->GetLastStatus() != Ok) { delete bmp; bmp = NULL; } // GDI+ under Windows XP sometimes fails to extract JPEG image dimensions if (bmp && Img_JPEG == format && (0 == bmp->GetWidth() || 0 == bmp->GetHeight())) { delete bmp; bmp = fitz::ImageFromData(data, len); } return bmp; }
// cf. http://stackoverflow.com/questions/4598872/creating-hbitmap-from-memory-buffer/4616394#4616394 Bitmap *BitmapFromData(const char *data, size_t len) { ImgFormat format = GfxFormatFromData(data, len); if (Img_TGA == format) return tga::ImageFromData(data, len); ScopedComPtr<IStream> stream(CreateStreamFromData(data, len)); if (!stream) return NULL; if (Img_JXR == format) return WICDecodeImageFromStream(stream); Bitmap *bmp = Bitmap::FromStream(stream); if (bmp && bmp->GetLastStatus() != Ok) { delete bmp; bmp = NULL; } // GDI+ under Windows XP sometimes fails to extract JPEG image dimensions if (bmp && Img_JPEG == format && 0 == bmp->GetWidth() && 0 == bmp->GetHeight()) { delete bmp; LARGE_INTEGER zero = { 0 }; stream->Seek(zero, STREAM_SEEK_SET, NULL); bmp = WICDecodeImageFromStream(stream); } return bmp; }
/******************************************************************** GdipBitmapFromFile - read a GDI+ image from a file. ********************************************************************/ extern "C" HRESULT DAPI GdipBitmapFromFile( __in_z LPCWSTR wzFileName, __out Bitmap **ppBitmap ) { HRESULT hr = S_OK; Bitmap *pBitmap = NULL; Status gs = Ok; ExitOnNull(ppBitmap, hr, E_INVALIDARG, "Invalid null wzFileName"); pBitmap = Bitmap::FromFile(wzFileName); ExitOnNull(pBitmap, hr, E_OUTOFMEMORY, "Failed to allocate bitmap from file."); gs = pBitmap->GetLastStatus(); ExitOnGdipFailure(gs, hr, "Failed to load bitmap from file: %ls", wzFileName); *ppBitmap = pBitmap; pBitmap = NULL; LExit: if (pBitmap) { delete pBitmap; } return hr; }
// 读取图片(从文件读) BOOL LoadBitmapFromFile(const CString strPathFile, CBitmap &bitmap, CSize &size) { HBITMAP hBitmap = NULL; #ifdef _UNICODE Bitmap* pBitmap = Bitmap::FromFile(strPathFile); #else Bitmap* pBitmap = Bitmap::FromFile(CEncodingUtil::AnsiToUnicode(strPathFile)); #endif Status status = pBitmap->GetLastStatus(); if(Ok == status) { status = pBitmap->GetHBITMAP(Color(0,0,0), &hBitmap); if(Ok == status) { if(bitmap.m_hObject != NULL) { bitmap.Detach(); } bitmap.Attach(hBitmap); BITMAP bmInfo; ::GetObject( bitmap.m_hObject, sizeof(BITMAP), &bmInfo ); size.cx = bmInfo.bmWidth; size.cy = bmInfo.bmHeight; delete pBitmap; return TRUE; } } return FALSE; }
HBITMAP loadImageFromBuffer(const void* buf, unsigned int size, HWND hWnd, const BOOL& keepAspect, const BOOL& resize) { if (!buf) { return NULL; } if (!bUseGdip) { return loadPNGFromBuffer(buf, size, hWnd, keepAspect, resize); } HGLOBAL hBuffer = ::GlobalAlloc(GMEM_MOVEABLE, size); if (!hBuffer) { return NULL; } Bitmap* pBitmap = NULL; Status stat; void* pBuffer = ::GlobalLock(hBuffer); if (pBuffer) { memcpy(pBuffer, buf, size); IStream* pStream = NULL; if (::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream) == S_OK) { // create a new Image object based on pStream pBitmap = Bitmap::FromStream(pStream); stat = pBitmap->GetLastStatus(); pStream->Release(); } ::GlobalUnlock(hBuffer); } ::GlobalFree(hBuffer); if (stat != Ok) { if (pBitmap) { delete pBitmap; } return NULL; } HBITMAP hBitmap = NULL; pBitmap->GetHBITMAP(color, &hBitmap); if (resize) { hBitmap = resizeBitmap(hWnd, hBitmap, pBitmap->GetWidth(), pBitmap->GetHeight(), keepAspect); } if (pBitmap) { delete pBitmap; } return hBitmap; }
// 读取图片(从资源读) BOOL LoadBitmapFromIDResource(UINT nID, CBitmap &bitmap, CSize &size, CString strType) { HINSTANCE hInst = AfxGetResourceHandle(); HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID), strType); if (!hRsrc) { return FALSE; } DWORD len = SizeofResource(hInst, hRsrc); BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc); if (!lpRsrc) { return FALSE; } HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len); BYTE* pmem = (BYTE*)GlobalLock(m_hMem); memcpy(pmem,lpRsrc,len); IStream* pstm; CreateStreamOnHGlobal(m_hMem,FALSE,&pstm); Bitmap* pBitmap = Gdiplus::Bitmap::FromStream(pstm); GlobalUnlock(m_hMem); GlobalFree(m_hMem); pstm->Release(); FreeResource(lpRsrc); HBITMAP hBitmap = NULL; Status status = pBitmap->GetLastStatus(); if(Ok == status) { status = pBitmap->GetHBITMAP(Color(0,0,0), &hBitmap); delete pBitmap; if(Ok == status) { if(bitmap.m_hObject != NULL) { bitmap.Detach(); } bitmap.Attach(hBitmap); BITMAP bmInfo; ::GetObject( bitmap.m_hObject, sizeof(BITMAP), &bmInfo ); size.cx = bmInfo.bmWidth; size.cy = bmInfo.bmHeight; return TRUE; } } return FALSE; }
// 读取图标(从内存中加载) BOOL LoadIconFromMem(BYTE* pByte, DWORD dwSize, HICON &hIcon) { // 根据文件大小分配HGLOBAL内存 HGLOBAL hGlobal = GlobalAlloc( GMEM_MOVEABLE | GMEM_NODISCARD, dwSize ); if ( !hGlobal ) { TRACE( _T( "Load (file): Error allocating memory\n" ) ); return FALSE; }; char *pData = reinterpret_cast<char*>(GlobalLock(hGlobal)); if ( !pData ) { TRACE( _T( "Load (file): Error locking memory\n" ) ); GlobalFree( hGlobal ); return FALSE; }; // 将文件内容读到HGLOBAL内存中 memcpy(pData, pByte, dwSize); GlobalUnlock( hGlobal ); // 利用hGlobal内存中的数据创建stream IStream *pStream = NULL; if ( CreateStreamOnHGlobal( hGlobal, TRUE, &pStream ) != S_OK ) { return FALSE; } Bitmap* pBitmap = Gdiplus::Bitmap::FromStream(pStream); // 要加上这一句,否则由GlobalAlloc得来的hGlobal内存没有被释放,导致内存泄露,由于 // CreateStreamOnHGlobal第二个参数被设置为TRUE,所以调用pStream->Release()会自动 // 将hGlobal内存(参见msdn对CreateStreamOnHGlobal的说明) pStream->Release(); HBITMAP hBitmap = NULL; Status status = pBitmap->GetLastStatus(); if(Ok == status) { status = pBitmap->GetHICON(&hIcon); delete pBitmap; if(Ok == status) { return TRUE; } } return FALSE; }
int SSkinGif::LoadFromFile( LPCTSTR pszFileName ) { Bitmap *pImg = Bitmap::FromFile(S_CT2W(pszFileName)); if(!pImg) return 0; if(pImg->GetLastStatus() != Gdiplus::Ok) { delete pImg; return 0; } LoadFromGdipImage(pImg); delete pImg; return m_nFrames; }
LIBELCBASEUI_API BOOL LoadImageFromBuffer(LPBYTE lpBuffer, int cbBuffer, CBitmap* pBitmap, CSize& size) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); if (!lpBuffer || cbBuffer <= 0 || !pBitmap) return FALSE; IStream* pstm = NULL; Bitmap *pImage = NULL; BOOL bSuccessful = FALSE; PBYTE pMem = NULL; HGLOBAL hMem = NULL; do { hMem = GlobalAlloc(GMEM_FIXED, cbBuffer); pMem = (BYTE*)GlobalLock(hMem); memcpy(pMem, lpBuffer, cbBuffer); CreateStreamOnHGlobal(hMem, FALSE, &pstm); pImage = Bitmap::FromStream(pstm); if (!pImage || pImage->GetLastStatus() != Ok) break; HBITMAP hBitmap = NULL; pImage->GetHBITMAP(Color::White, &hBitmap); pBitmap->DeleteObject(); if (!pBitmap->Attach(hBitmap)) break; BITMAP bm; GetObject(pBitmap->m_hObject, sizeof(bm), &bm); size.cx = pImage->GetWidth(); size.cy = pImage->GetHeight(); bSuccessful = TRUE; } while (0); if (hMem) GlobalUnlock(hMem); if (pstm) pstm->Release(); if (pImage) delete pImage; return bSuccessful; }
Bitmap* CExampleDemoDlg::ReadBitmap(string path) { const char* szName = path.c_str(); WCHAR wstr[1000]; MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szName, -1, wstr, 1000); Bitmap* pInImage = Bitmap::FromFile(wstr); if (pInImage->GetLastStatus() == -1) { SAFE_DELETE(pInImage); return NULL; } return pInImage; }
vector<Bitmap*> CExampleDemoDlg::LoadTemplateImg(string filesrc) { vector<Bitmap*> tempplate; vector<string>filepathname; ScanDirectory(filesrc, ".jpg", filepathname);//filesrc是文件夹名字 //std::sort(filepathname.begin(),filepathname.end()); for (int i = 0; i < filepathname.size(); i++) { string image = filesrc+"\\"+ filepathname[i]; std::wstring widestr = std::wstring(image.begin(), image.end()); Bitmap* pInImage = Bitmap::FromFile(widestr.c_str()); if (pInImage->GetLastStatus() == -1) { SAFE_DELETE(pInImage); continue; } Bitmap* img = pInImage->Clone(0, 0, pInImage->GetWidth(), pInImage->GetHeight(), PixelFormat32bppARGB); tempplate.push_back(img); } return tempplate; }
BOOL GDImage::_LoadImage( const WCHAR *pImageFilename ) { if ( m_filename == std::wstring(pImageFilename ? pImageFilename : L"") ) { return true; } if ( m_pImage != NULL ) { m_filename.clear(); delete m_pImage; m_pImage = NULL; } if ( pImageFilename == NULL ) { return TRUE; } // Try to laod the file if it exists //Bitmap *pNewImage = Bitmap::FromFile( pImageFilename ); Bitmap *pNewImage = new Bitmap( pImageFilename ); Status loadStatus = pNewImage->GetLastStatus(); if ( loadStatus != Ok ) { // Failed to laod image delete pNewImage; return FALSE; } m_filename = pImageFilename; m_pImage = pNewImage; return TRUE; }
/******************************************************************** GdipBitmapFromResource - read a GDI+ image out of a resource stream ********************************************************************/ extern "C" HRESULT DAPI GdipBitmapFromResource( __in_opt HINSTANCE hinst, __in_z LPCSTR szId, __out Bitmap **ppBitmap ) { HRESULT hr = S_OK; LPVOID pvData = NULL; DWORD cbData = 0; HGLOBAL hGlobal = NULL;; LPVOID pv = NULL; IStream *pStream = NULL; Bitmap *pBitmap = NULL; Status gs = Ok; hr = ResReadData(hinst, szId, &pvData, &cbData); ExitOnFailure(hr, "Failed to load GDI+ bitmap from resource."); // Have to copy the fixed resource data into moveable (heap) memory // since that's what GDI+ expects. hGlobal = ::GlobalAlloc(GMEM_MOVEABLE, cbData); ExitOnNullWithLastError(hGlobal, hr, "Failed to allocate global memory."); pv = ::GlobalLock(hGlobal); ExitOnNullWithLastError(pv, hr, "Failed to lock global memory."); memcpy(pv, pvData, cbData); ::GlobalUnlock(pv); // no point taking any more memory than we have already pv = NULL; hr = ::CreateStreamOnHGlobal(hGlobal, TRUE, &pStream); ExitOnFailure(hr, "Failed to allocate stream from global memory."); hGlobal = NULL; // we gave the global memory to the stream object so it will close it pBitmap = Bitmap::FromStream(pStream); ExitOnNull(pBitmap, hr, E_OUTOFMEMORY, "Failed to allocate bitmap from stream."); gs = pBitmap->GetLastStatus(); ExitOnGdipFailure(gs, hr, "Failed to load bitmap from stream."); *ppBitmap = pBitmap; pBitmap = NULL; LExit: if (pBitmap) { delete pBitmap; } ReleaseObject(pStream); if (pv) { ::GlobalUnlock(pv); } if (hGlobal) { ::GlobalFree(hGlobal); } return hr; }
//---------------------------------------------------------------------------------------------------------------------- // DO IMAGE LIST //---------------------------------------------------------------------------------------------------------------------- void cListView :: do_image_list ( const cFigViewItemList * pList ) { mojo::cPtI IconSize = get_icon_size (); int iDimX = IconSize.x; int iDimY = IconSize.y; HIMAGELIST hIL = ImageList_Create ( iDimX, iDimY, LR_CREATEDIBSECTION | ILC_COLOR32, pList->qty(), 1 ); //------------------------------------------ // LOAD DEFAULT IMAGES //------------------------------------------ const int * aiBitmap = default_bitmap_ids (); for ( int i = 0; aiBitmap[i]; i++ ) { HANDLE hBitmap = LoadImage ( g_hInstance, MAKEINTRESOURCE ( aiBitmap[i] ), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION ); ImageList_Add ( hIL, (HBITMAP) hBitmap, NULL ); } int iItemIndex = 0; for ( cFigViewItem * p = pList->pHead; p; p = p->pNext, iItemIndex++ ) { bool bLoadedFromFile = false; int iImageIndex = 0; //------------------------------- // TRY TO LOAD IMAGE FROM FILE //------------------------------- if ( p->sIconPath.len() ) { if ( ! file_exists ( p->sIconPath.cstr() ) ) { mojo::put_ad_lib_memo ( mojo::cMemo::error, L"Image file not found", L"%s", p->sIconPath.cstr() ); cStrW s; s.f ( L"Image file not found: %s", p->sIconPath.cstr() ); LOG ( s.cstr() ); } else { HICON hIcon; Bitmap bm ( p->sIconPath.cstr() ); if ( ! ( Ok == bm.GetLastStatus() ) ) LOG_V ( L"Bitmap constructor failed with %s.", p->sIconPath.cstr() ); else { bm.GetHICON(&hIcon); if ( Ok != bm.GetLastStatus() ) LOG_V ( L"Bitmap::GetHICON() failed with %s", p->sIconPath.cstr() ); else { iImageIndex = ImageList_AddIcon( hIL, hIcon ); bLoadedFromFile = true; } } if ( ! bLoadedFromFile) mojo::put_ad_lib_memo ( mojo::cMemo::error, L"Unable to display image file", L"%s", p->sIconPath.cstr() ); } } if ( ! bLoadedFromFile ) { iImageIndex = 0;; } #if 0 LVITEM lvi; ZeroMemory ( &lvi, sizeof(lvi) ); lvi.mask = LVIF_IMAGE; lvi.iItem = iItemIndex; lvi.iImage = iImageIndex; ListView_SetItem ( hwnd, &lvi ); #endif } HIMAGELIST hResult = ListView_SetImageList ( hwnd, hIL, LVSIL_NORMAL ); hResult; }
/* ** Sets the system wallpapar. ** */ void System::SetWallpaper(const std::wstring& wallpaper, const std::wstring& style) { if (!wallpaper.empty()) { if (_waccess(wallpaper.c_str(), 0) == -1) { LogErrorF(L"!SetWallpaper: Unable to read file: %s", wallpaper.c_str()); return; } Bitmap* bitmap = Bitmap::FromFile(wallpaper.c_str()); if (bitmap && bitmap->GetLastStatus() == Ok) { std::wstring file = GetRainmeter().GetSettingsPath() + L"Wallpaper.bmp"; const CLSID bmpClsid = { 0x557cf400, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } }; if (bitmap->Save(file.c_str(), &bmpClsid) == Ok) { if (!style.empty()) { HKEY hKey; if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) { const WCHAR* wallStyle = nullptr; const WCHAR* wallTile = L"0"; const WCHAR* option = style.c_str(); if (_wcsicmp(option, L"CENTER") == 0) { wallStyle = L"0"; } else if (_wcsicmp(option, L"TILE") == 0) { wallStyle = L"0"; wallTile = L"1"; } else if (_wcsicmp(option, L"STRETCH") == 0) { wallStyle = L"2"; } else if (Platform::IsAtLeastWin7()) { if (_wcsicmp(option, L"FIT") == 0) { wallStyle = L"6"; } else if (_wcsicmp(option, L"FILL") == 0) { wallStyle = L"10"; } } if (wallStyle) { RegSetValueEx(hKey, L"WallpaperStyle", 0, REG_SZ, (const BYTE*)wallStyle, sizeof(WCHAR) * 2); RegSetValueEx(hKey, L"TileWallpaper", 0, REG_SZ, (const BYTE*)wallTile, sizeof(WCHAR) * 2); } else { LogError(L"!SetWallpaper: Invalid style"); } RegCloseKey(hKey); } } SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)file.c_str(), SPIF_UPDATEINIFILE); } } delete bitmap; } }
// 读取图片(从内存中加载) BOOL LoadBitmapFromMem(BYTE* pByte, DWORD dwSize, CBitmap &bitmap, CSize &size) { // 根据文件大小分配HGLOBAL内存 HGLOBAL hGlobal = GlobalAlloc( GMEM_MOVEABLE | GMEM_NODISCARD, dwSize ); if ( !hGlobal ) { TRACE( _T( "Load (file): Error allocating memory\n" ) ); return FALSE; }; char *pData = reinterpret_cast<char*>(GlobalLock(hGlobal)); if ( !pData ) { TRACE( _T( "Load (file): Error locking memory\n" ) ); GlobalFree( hGlobal ); return FALSE; }; // 将文件内容读到HGLOBAL内存中 memcpy(pData, pByte, dwSize); GlobalUnlock( hGlobal ); // 利用hGlobal内存中的数据创建stream IStream *pStream = NULL; if ( CreateStreamOnHGlobal( hGlobal, TRUE, &pStream ) != S_OK ) { return FALSE; } Bitmap* pBitmap = Gdiplus::Bitmap::FromStream(pStream); // 要加上这一句,否则由GlobalAlloc得来的hGlobal内存没有被释放,导致内存泄露,由于 // CreateStreamOnHGlobal第二个参数被设置为TRUE,所以调用pStream->Release()会自动 // 将hGlobal内存(参见msdn对CreateStreamOnHGlobal的说明) pStream->Release(); HBITMAP hBitmap = NULL; Status status = pBitmap->GetLastStatus(); if(Ok == status) { status = pBitmap->GetHBITMAP(Color(0,0,0), &hBitmap); delete pBitmap; if(Ok == status) { if(bitmap.m_hObject != NULL) { bitmap.Detach(); } bitmap.Attach(hBitmap); BITMAP bmInfo; ::GetObject( bitmap.m_hObject, sizeof(BITMAP), &bmInfo ); size.cx = bmInfo.bmWidth; size.cy = bmInfo.bmHeight; return TRUE; } } return FALSE; }
/* ** Loads the image from file handle ** */ Bitmap* TintedImage::LoadImageFromFileHandle(HANDLE fileHandle, DWORD fileSize, HGLOBAL* phBuffer) { HGLOBAL hBuffer = ::GlobalAlloc(GMEM_MOVEABLE, fileSize); if (hBuffer) { void* pBuffer = ::GlobalLock(hBuffer); if (pBuffer) { DWORD readBytes; ReadFile(fileHandle, pBuffer, fileSize, &readBytes, nullptr); ::GlobalUnlock(hBuffer); IStream* pStream = nullptr; if (::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream) == S_OK) { Bitmap* bitmap = Bitmap::FromStream(pStream); pStream->Release(); if (Ok == bitmap->GetLastStatus()) { GUID guid; if (Ok == bitmap->GetRawFormat(&guid) && guid != ImageFormatIcon) { // Gather EXIF orientation information if (m_UseExifOrientation) { UINT size = bitmap->GetPropertyItemSize(PropertyTagOrientation); if (size) { RotateFlipType flip = RotateNoneFlipNone; PropertyItem* orientation = (PropertyItem*)new BYTE[size]; bitmap->GetPropertyItem(PropertyTagOrientation, size, orientation); if (orientation) { switch(*(short*)orientation->value) { case 8: flip = Rotate270FlipNone; break; case 7: flip = Rotate270FlipX; break; case 6: flip = Rotate90FlipNone; break; case 5: flip = Rotate90FlipX; break; case 4: flip = Rotate180FlipX; break; case 3: flip = Rotate180FlipNone; break; case 2: flip = RotateNoneFlipX; break; default: flip = RotateNoneFlipNone; } bitmap->RotateFlip(flip); } delete [] orientation; } } //////////////////////////////////////////// // Convert loaded image to faster blittable bitmap (may increase memory usage slightly) Rect r(0, 0, bitmap->GetWidth(), bitmap->GetHeight()); Bitmap* clone = new Bitmap(r.Width, r.Height, PixelFormat32bppPARGB); { Graphics graphics(clone); graphics.DrawImage(bitmap, r, 0, 0, r.Width, r.Height, UnitPixel); } delete bitmap; bitmap = clone; ::GlobalFree(hBuffer); hBuffer = nullptr; //////////////////////////////////////////// } *phBuffer = hBuffer; return bitmap; } delete bitmap; } } ::GlobalFree(hBuffer); } *phBuffer = nullptr; return nullptr; }
int loadImage(struct textureTableIndexStruct *tti, char *fname) { /* http://msdn.microsoft.com/en-us/library/ms536298(VS.85).aspx GDI+ Lockbits example - what this function is based on*/ /* http://www.microsoft.com/downloads/details.aspx?FamilyID=6a63ab9c-df12-4d41-933c-be590feaa05a&DisplayLang=en GDI+ redistributable download - gdiplus.dll 2MB */ if(!loaded) { initImageLoader(); loaded = 1; } // convert to wide char http://msdn.microsoft.com/en-us/library/ms235631(VS.80).aspx //fname = "C:/source2/freewrl/freex3d/tests/helpers/brick.png"; //fname = "junk.jpg"; //test failure condition size_t origsize = strlen(fname) + 1; char* fname2 = (char*) malloc(origsize); strcpy(fname2,fname); for(int jj=0;jj<strlen(fname2);jj++) if(fname2[jj] == '/' ) fname2[jj] = '\\'; const size_t newsize = 225; size_t convertedChars = 0; wchar_t wcstring[newsize]; //mbstowcs_s(&convertedChars, wcstring, origsize, fname, _TRUNCATE); #if _MSC_VER >= 1500 mbstowcs_s(&convertedChars, wcstring, origsize, fname2, _TRUNCATE); #else mbstowcs(wcstring, fname2, MB_CUR_MAX); #endif free(fname2); Bitmap *bitmap = NULL; Status stat; bitmap = Bitmap::FromFile(wcstring,false); //new Bitmap(wcstring); //or Bitmap::FromFile(wcstring,false); L"LockBitsTest1.bmp"); // verifying the success of constructors http://msdn.microsoft.com/en-us/library/ms533801(VS.85).aspx stat = bitmap->GetLastStatus(); // http://msdn.microsoft.com/en-us/library/ms535410(VS.85).aspx if(stat != Ok) return 0; //should come here if it can't find the image file BitmapData* bitmapData = new BitmapData; //#define verbose 1 #ifdef verbose printf("bitmap W=%d H=%d\n",bitmap->GetWidth(),bitmap->GetHeight()); /* http://msdn.microsoft.com/en-us/library/ms535387(VS.85).aspx GetPixelFormat http://msdn.microsoft.com/en-us/library/ms534412(v=VS.85).aspx pixelFormat constants http://msdn.microsoft.com/en-us/library/ms534136(v=VS.85).aspx Image::GetFlags ImageFlagsColorSpaceGRAY = 0x0040, */ UINT flags = bitmap->GetFlags(); printf("The value of flags, in hexadecimal form, is %x.\n", flags); // Is the ColorSpaceRGB flag set? if(flags & ImageFlagsColorSpaceRGB) printf("The ColorSpaceRGB flag is set.\n"); else if(flags & ImageFlagsColorSpaceGRAY) printf("The ColorSpaceGRAY flag is set.\n"); printf("bitmap format index =%d %d\n",bitmap->GetPixelFormat()%256,bitmap->GetPixelFormat()); if(Gdiplus::IsAlphaPixelFormat(bitmap->GetPixelFormat()) ) printf("has alpha channel\n"); else printf("no alpha channel\n"); if(Gdiplus::IsCanonicalPixelFormat(bitmap->GetPixelFormat()) ) printf("is canonical\n"); else printf("not canonical\n"); printf("Number of bits per pixel %d\n",Gdiplus::GetPixelFormatSize(bitmap->GetPixelFormat())); #endif #undef verbose bool flipVertically = true; Rect rect(0,0,bitmap->GetWidth(),bitmap->GetHeight()); if(flipVertically) bitmapData->Stride = -bitmap->GetWidth()*4; else bitmapData->Stride = bitmap->GetWidth()*4; bitmapData->Width = bitmap->GetWidth(); bitmapData->Height = bitmap->GetHeight(); bitmapData->PixelFormat = PixelFormat32bppARGB; int totalbytes = bitmap->GetWidth() * bitmap->GetHeight() * 4; //tti->depth; unsigned char * blob = (unsigned char*)malloc(totalbytes); if(flipVertically) bitmapData->Scan0 = &blob[bitmap->GetWidth()*bitmap->GetHeight()*4 + bitmapData->Stride]; else bitmapData->Scan0 = blob; // Lock a rectangular portion of the bitmap for reading. bitmap->LockBits( &rect, ImageLockModeRead|ImageLockModeUserInputBuf, PixelFormat32bppARGB, //PixelFormat24bppRGB, bitmapData); #ifdef verbose printf("The stride is %d.\n\n", bitmapData->Stride); printf("bitmapData W=%d H=%d\n",bitmapData->Width,bitmapData->Height); #endif #ifdef verbose // Display the hexadecimal value of each pixel in the 5x3 rectangle. UINT* pixels = (UINT*)bitmapData->Scan0; for(UINT row = 0; row < 23; ++row) { for(UINT col = 0; col < 5; ++col) { printf("%x\n", pixels[row * bitmapData->Stride / 4 + col]); } printf("- - - - - - - - - - \n"); } #endif //deep copy data so browser owns it (and does its FREE_IF_NZ) and we can delete our copy here and forget about it tti->x = bitmapData->Width; tti->y = bitmapData->Height; tti->frames = 1; tti->texdata = blob; if(!blob) printf("ouch in gdiplus image loader L140 - no image data\n"); //tti->hasAlpha = Gdiplus::IsAlphaPixelFormat(bitmapData->PixelFormat)?1:0; tti->hasAlpha = Gdiplus::IsAlphaPixelFormat(bitmap->GetPixelFormat())?1:0; //printf("fname=%s alpha=%ld\n",fname,tti->hasAlpha); #ifdef verbose for(UINT row = 0; row < 23; ++row) { for(UINT col = 0; col < 5; ++col) { //printf("%x\n", *(UINT*)&(tti->texdata[(row * bitmapData->Stride / 4 + col)*tti->depth])); printf("%x\n", *(UINT*)&(tti->texdata[(row * tti->x + col)*4])); //tti->depth])); } printf("- - - - - - - - - - \n"); } #endif tti->filename = fname; // wrong: tti->status = TEX_NEEDSBINDING; //make this the last thing you set, because another thread is watching ready to bind // wrong - let the calling function set the status otherwise textures disappear sometimes bitmap->UnlockBits(bitmapData); delete bitmapData; delete bitmap; //shutdownImageLoader(); //we'll keep it loaded if(0) { shutdownImageLoader(); loaded = 0; } return 1; }