//----------------------------------------------------------------------------- // Does: Open a File And Load It Into IPicture (Interface) // ~~~~ (.BMP .DIB .EMF .GIF .ICO .JPG .WMF) // // InPut: sFilePathName - Path And FileName Target To Save // ~~~~~ // // OutPut: TRUE If Succeeded... // ~~~~~~ //----------------------------------------------------------------------------- BOOL CPicViewer::Load(CString sFilePathName) //============================================================================= { BOOL bResult = FALSE; CFile PictureFile; CFileException e; int nSize = 0; if(m_IPicture != NULL) FreePictureData(); // Important - Avoid Leaks... if(PictureFile.Open(sFilePathName, CFile::modeRead | CFile::typeBinary, &e)) { nSize = PictureFile.GetLength(); BYTE* pBuffer = new BYTE[nSize]; if(PictureFile.Read(pBuffer, nSize) > 0) { // 防止图像文件数据有错(目前的问题是无结束符),导致OleLoadPicture无响应 [6/22/2009 guowenpeng] if ((pBuffer[nSize - 2] != 0xff) || (pBuffer[nSize - 1] != 0xd9)) // 0xffd9: jpeg文件结束标志 { pBuffer[nSize - 2] = 0xff; pBuffer[nSize - 1] = 0xd9; } if(LoadPictureData(pBuffer, nSize)) bResult = TRUE; } PictureFile.Close(); delete [] pBuffer; } else // Open Failed... { TCHAR szCause[255]; e.GetErrorMessage(szCause, 255, NULL); TRACE( "%s\n", szCause ); // HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd; // MessageBoxEx(hWnd, szCause, ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH); bResult = FALSE; } m_Weight = nSize; // Update Picture Size Info... if(m_IPicture != NULL) // Do Not Try To Read From Memory That Is Not Exist... { m_IPicture->get_Height(&m_Height); m_IPicture->get_Width(&m_Width); // Calculate Its Size On a "Standard" (96 DPI) Device Context m_Height = MulDiv(m_Height, 96, HIMETRIC_INCH); m_Width = MulDiv(m_Width, 96, HIMETRIC_INCH); } else // Picture Data Is Not a Known Picture Type { m_Height = 0; m_Width = 0; bResult = FALSE; } return(bResult); }
CPicture::~CPicture() { FreePictureData(); // Important - Avoid Leaks... delete pBitmap; if (bHaveGDIPlus) GdiplusShutdown(gdiplusToken); }
//----------------------------------------------------------------------------- // Does: Load It Into IPicture (Interface) // ~~~~ (.BMP .DIB .EMF .GIF .ICO .JPG .WMF) // // InPut: Buffer Of Data Source (File / Resource) And Its Size // ~~~~~ // // OutPut: TRUE If Succeeded... // ~~~~~~ //----------------------------------------------------------------------------- BOOL CPicViewer::Load(BYTE *pBuffer, int nSize) //============================================================================= { BOOL bResult = FALSE; if(m_IPicture != NULL) FreePictureData(); // Important - Avoid Leaks... if(LoadPictureData(pBuffer, nSize)) { bResult = TRUE; } m_Weight = nSize; // Update Picture Size Info... if(m_IPicture != NULL) // Do Not Try To Read From Memory That Is Not Exist... { m_IPicture->get_Height(&m_Height); m_IPicture->get_Width(&m_Width); // Calculate Its Size On a "Standard" (96 DPI) Device Context m_Height = MulDiv(m_Height, 96, HIMETRIC_INCH); m_Width = MulDiv(m_Width, 96, HIMETRIC_INCH); } else // Picture Data Is Not a Known Picture Type { m_Height = 0; m_Width = 0; bResult = FALSE; } return(bResult); }
bool CPicture::Load(tstring sFilePathName) { bool bResult = false; bIsIcon = false; lpIcons = NULL; //CFile PictureFile; //CFileException e; FreePictureData(); // Important - Avoid Leaks... // No-op if no file specified if (sFilePathName.empty()) return true; // Load & initialize the GDI+ library if available HMODULE hGdiPlusLib = AtlLoadSystemLibraryUsingFullPath(_T("gdiplus.dll")); if (hGdiPlusLib && GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) == Ok) { bHaveGDIPlus = true; } // Since we loaded the gdiplus.dll only to check if it's available, we // can safely free the library here again - GdiplusStartup() loaded it too // and reference counting will make sure that it stays loaded until GdiplusShutdown() // is called. FreeLibrary(hGdiPlusLib); // Attempt to load using GDI+ if available if (bHaveGDIPlus) { pBitmap = new Bitmap(sFilePathName.c_str(), FALSE); GUID guid; pBitmap->GetRawFormat(&guid); if (pBitmap->GetLastStatus() != Ok) { delete pBitmap; pBitmap = NULL; } // gdiplus only loads the first icon found in an icon file // so we have to handle icon files ourselves :( // Even though gdiplus can load icons, it can't load the new // icons from Vista - in Vista, the icon format changed slightly. // But the LoadIcon/LoadImage API still can load those icons, // at least those dimensions which are also used on pre-Vista // systems. // For that reason, we don't rely on gdiplus telling us if // the image format is "icon" or not, we also check the // file extension for ".ico". std::transform(sFilePathName.begin(), sFilePathName.end(), sFilePathName.begin(), ::tolower); bIsIcon = (guid == ImageFormatIcon) || (wcsstr(sFilePathName.c_str(), L".ico") != NULL) || (wcsstr(sFilePathName.c_str(), L".cur") != NULL); bIsTiff = (guid == ImageFormatTIFF) || (_tcsstr(sFilePathName.c_str(), _T(".tiff")) != NULL); m_Name = sFilePathName; if (bIsIcon) { // Icon file, get special treatment... if (pBitmap) { // Cleanup first... delete (pBitmap); pBitmap = NULL; bIsIcon = true; } CAutoFile hFile = CreateFile(sFilePathName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile) { BY_HANDLE_FILE_INFORMATION fileinfo; if (GetFileInformationByHandle(hFile, &fileinfo)) { lpIcons = new BYTE[fileinfo.nFileSizeLow]; DWORD readbytes; if (ReadFile(hFile, lpIcons, fileinfo.nFileSizeLow, &readbytes, NULL)) { // we have the icon. Now gather the information we need later if (readbytes >= sizeof(ICONDIR)) { // we are going to open same file second time so we have to close the file now hFile.CloseHandle(); LPICONDIR lpIconDir = (LPICONDIR)lpIcons; if ((lpIconDir->idCount) && ((lpIconDir->idCount * sizeof(ICONDIR)) <= fileinfo.nFileSizeLow)) { try { bResult = false; nCurrentIcon = 0; hIcons = new HICON[lpIconDir->idCount]; // check that the pointers point to data that we just loaded if (((BYTE*)lpIconDir->idEntries > (BYTE*)lpIconDir) && (((BYTE*)lpIconDir->idEntries) + (lpIconDir->idCount * sizeof(ICONDIRENTRY)) < ((BYTE*)lpIconDir) + fileinfo.nFileSizeLow)) { m_Width = lpIconDir->idEntries[0].bWidth; m_Height = lpIconDir->idEntries[0].bHeight; bResult = true; for (int i=0; i<lpIconDir->idCount; ++i) { hIcons[i] = (HICON)LoadImage(NULL, sFilePathName.c_str(), IMAGE_ICON, lpIconDir->idEntries[i].bWidth, lpIconDir->idEntries[i].bHeight, LR_LOADFROMFILE); if (hIcons[i] == NULL) { // if the icon couldn't be loaded, the data is most likely corrupt delete [] lpIcons; lpIcons = NULL; bResult = false; break; } } } } catch (...) { delete [] lpIcons; lpIcons = NULL; bResult = false; } } else { delete [] lpIcons; lpIcons = NULL; bResult = false; } } else { delete [] lpIcons; lpIcons = NULL; bResult = false; } } else { delete [] lpIcons; lpIcons = NULL; } } } } else if (pBitmap) // Image loaded successfully with GDI+ { m_Height = pBitmap->GetHeight(); m_Width = pBitmap->GetWidth(); bResult = true; } // If still failed to load the file... if (!bResult) { // Attempt to load the FreeImage library as an optional DLL to support additional formats // NOTE: Currently just loading via FreeImage & using GDI+ for drawing. // It might be nice to remove this dependency in the future. HMODULE hFreeImageLib = LoadLibrary(_T("FreeImage.dll")); // FreeImage DLL functions typedef const char* (__stdcall *FreeImage_GetVersion_t)(void); typedef int (__stdcall *FreeImage_GetFileType_t)(const TCHAR *filename, int size); typedef int (__stdcall *FreeImage_GetFIFFromFilename_t)(const TCHAR *filename); typedef void* (__stdcall *FreeImage_Load_t)(int format, const TCHAR *filename, int flags); typedef void (__stdcall *FreeImage_Unload_t)(void* dib); typedef int (__stdcall *FreeImage_GetColorType_t)(void* dib); typedef unsigned (__stdcall *FreeImage_GetWidth_t)(void* dib); typedef unsigned (__stdcall *FreeImage_GetHeight_t)(void* dib); typedef void (__stdcall *FreeImage_ConvertToRawBits_t)(BYTE *bits, void *dib, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown); //FreeImage_GetVersion_t FreeImage_GetVersion = NULL; FreeImage_GetFileType_t FreeImage_GetFileType = NULL; FreeImage_GetFIFFromFilename_t FreeImage_GetFIFFromFilename = NULL; FreeImage_Load_t FreeImage_Load = NULL; FreeImage_Unload_t FreeImage_Unload = NULL; //FreeImage_GetColorType_t FreeImage_GetColorType = NULL; FreeImage_GetWidth_t FreeImage_GetWidth = NULL; FreeImage_GetHeight_t FreeImage_GetHeight = NULL; FreeImage_ConvertToRawBits_t FreeImage_ConvertToRawBits = NULL; if (hFreeImageLib) { bool exportsValid = true; //FreeImage_GetVersion = (FreeImage_GetVersion_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetVersion@0", valid); FreeImage_GetWidth = (FreeImage_GetWidth_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetWidth@4", exportsValid); FreeImage_GetHeight = (FreeImage_GetHeight_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetHeight@4", exportsValid); FreeImage_Unload = (FreeImage_Unload_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_Unload@4", exportsValid); FreeImage_ConvertToRawBits = (FreeImage_ConvertToRawBits_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_ConvertToRawBits@32", exportsValid); #ifdef UNICODE FreeImage_GetFileType = (FreeImage_GetFileType_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFileTypeU@8", exportsValid); FreeImage_GetFIFFromFilename = (FreeImage_GetFIFFromFilename_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFIFFromFilenameU@4", exportsValid); FreeImage_Load = (FreeImage_Load_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_LoadU@12", exportsValid); #else FreeImage_GetFileType = (FreeImage_GetFileType_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFileType@8", exportsValid); FreeImage_GetFIFFromFilename = (FreeImage_GetFIFFromFilename_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFIFFromFilename@4", exportsValid); FreeImage_Load = (FreeImage_Load_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_Load@12", exportsValid); #endif //const char* version = FreeImage_GetVersion(); // Check the DLL is using compatible exports if (exportsValid) { // Derive file type from file header. int fileType = FreeImage_GetFileType(sFilePathName.c_str(), 0); if (fileType < 0) { // No file header available, attempt to parse file name for extension. fileType = FreeImage_GetFIFFromFilename(sFilePathName.c_str()); } // If we have a valid file type if (fileType >= 0) { void* dib = FreeImage_Load(fileType, sFilePathName.c_str(), 0); if (dib) { unsigned width = FreeImage_GetWidth(dib); unsigned height = FreeImage_GetHeight(dib); // Create a GDI+ bitmap to load into... pBitmap = new Bitmap(width, height, PixelFormat32bppARGB); if (pBitmap && pBitmap->GetLastStatus() == Ok) { // Write & convert the loaded data into the GDI+ Bitmap Rect rect(0, 0, width, height); BitmapData bitmapData; if (pBitmap->LockBits(&rect, ImageLockModeWrite, PixelFormat32bppARGB, &bitmapData) == Ok) { FreeImage_ConvertToRawBits((BYTE*)bitmapData.Scan0, dib, bitmapData.Stride, 32, 0xff << RED_SHIFT, 0xff << GREEN_SHIFT, 0xff << BLUE_SHIFT, FALSE); pBitmap->UnlockBits(&bitmapData); m_Width = width; m_Height = height; bResult = true; } else // Failed to lock the destination Bitmap { delete pBitmap; pBitmap = NULL; } } else // Bitmap allocation failed { delete pBitmap; pBitmap = NULL; } FreeImage_Unload(dib); dib = NULL; } } } FreeLibrary(hFreeImageLib); hFreeImageLib = NULL; } } }
//----------------------------------------------------------------------------- // Does: Open a Resource And Load It Into IPicture (Interface) // ~~~~ (.BMP .DIB .EMF .GIF .ICO .JPG .WMF) // // Note: When Adding a Bitmap Resource It Would Automatically Show On "Bitmap" // ~~~~ This NOT Good Coz We Need To Load It From a Custom Resource "BMP" // To Add a Custom Rresource: Import Resource -> Open As -> Custom // (Both .BMP And .DIB Should Be Found Under "BMP") // // InPut: ResourceName - As a UINT Defined (Example: IDR_PICTURE_RESOURCE) // ~~~~~ ResourceType - Type Name (Example: "JPG") // // OutPut: TRUE If Succeeded... // ~~~~~~ //----------------------------------------------------------------------------- BOOL CPicViewer::Load(UINT ResourceName, LPCSTR ResourceType) //============================================================================= { BOOL bResult = FALSE; HGLOBAL hGlobal = NULL; HRSRC hSource = NULL; LPVOID lpVoid = NULL; int nSize = 0; if(m_IPicture != NULL) FreePictureData(); // Important - Avoid Leaks... hSource = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(ResourceName), ResourceType); if(hSource == NULL) { TRACE( "FindResource() Failed\n" ); // HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd; // MessageBoxEx(hWnd, "FindResource() Failed\t", ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH); return(FALSE); } hGlobal = LoadResource(AfxGetResourceHandle(), hSource); if(hGlobal == NULL) { TRACE( "LoadResource() Failed\n" ); // HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd; // MessageBoxEx(hWnd, "LoadResource() Failed\t", ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH); return(FALSE); } lpVoid = LockResource(hGlobal); if(lpVoid == NULL) { TRACE( "LockResource() Failed\n" ); // HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd; // MessageBoxEx(hWnd, "LockResource() Failed\t", ERROR_TITLE, MB_OK | MB_ICONSTOP, LANG_ENGLISH); return(FALSE); } nSize = (UINT)SizeofResource(AfxGetResourceHandle(), hSource); if(LoadPictureData((BYTE*)hGlobal, nSize)) bResult = TRUE; UnlockResource(hGlobal); // 16Bit Windows Needs This FreeResource(hGlobal); // 16Bit Windows Needs This (32Bit - Automatic Release) m_Weight = nSize; // Update Picture Size Info... if(m_IPicture != NULL) // Do Not Try To Read From Memory That Is Not Exist... { m_IPicture->get_Height(&m_Height); m_IPicture->get_Width(&m_Width); // Calculate Its Size On a "Standard" (96 DPI) Device Context m_Height = MulDiv(m_Height, 96, HIMETRIC_INCH); m_Width = MulDiv(m_Width, 96, HIMETRIC_INCH); } else // Picture Data Is Not a Known Picture Type { m_Height = 0; m_Width = 0; bResult = FALSE; } return(bResult); }
//----------------------------------------------------------------------------- // Does: Destructor - Free Data And Information From The CPicture Object // ~~~~ // //----------------------------------------------------------------------------- CPicViewer::~CPicViewer() //============================================================================= { if(m_IPicture != NULL) FreePictureData(); // Important - Avoid Leaks... }