HBITMAP CEnBitmap::LoadImageFile(LPCTSTR szImagePath, COLORREF crBack) { int nType = GetFileType(szImagePath); //TRACE("Load(%ws)\n", szImagePath); switch (nType) { // i suspect it is more efficient to load // bmps this way since it avoids creating device contexts etc that the // IPicture methods requires. that method however is still valuable // since it handles other image types and transparency case FT_BMP: { HBITMAP bmp=(HBITMAP)::LoadImage(NULL, szImagePath, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); BITMAP bi; ::GetObject(bmp, sizeof( BITMAP ), &bi); BYTE bpp = bi.bmBitsPixel >> 3; if(bpp==4){ BYTE* pBits = new BYTE[ bi.bmWidth * bi.bmHeight * bpp ]; int p = ::GetBitmapBits( bmp, bi.bmWidth * bi.bmHeight * bpp, pBits); for (int y=0; y<bi.bmHeight; ++y) { BYTE *pPixel= (BYTE *) pBits + bi.bmWidth * 4 * y; for (int x=0; x<bi.bmWidth ; ++x) { pPixel[0]= pPixel[0]*pPixel[3]/255; pPixel[1]= pPixel[1]*pPixel[3]/255; pPixel[2]= pPixel[2]*pPixel[3]/255; pPixel+= 4; } } ::SetBitmapBits(bmp, bi.bmWidth*bi.bmHeight*bpp, pBits); delete pBits; } return bmp; } case FT_UNKNOWN: return NULL; default: // all the rest { USES_CONVERSION; IPicture* pPicture = NULL; HBITMAP hbm = NULL; HRESULT hr = OleLoadPicturePath(T2OLE((LPTSTR)szImagePath), NULL, 0, crBack, IID_IPicture, (LPVOID *)&pPicture); if (pPicture) { hbm = ExtractBitmap(pPicture, crBack); pPicture->Release(); } return hbm; } } return NULL; // can't get here }
void CXTPPropertyGridItemPicture::SetPicturePath(LPCTSTR lpszPath) { m_strPicturePath = lpszPath; LPPICTUREDISP pPict = NULL; if (OleLoadPicturePath((LPOLESTR)XTP_CT2CW(m_strPicturePath), NULL, 0, 0, IID_IPictureDisp, (LPVOID*)&pPict) == S_OK) { m_olePicture.SetPictureDispatch(pPict); pPict->Release(); OnValueChanged(_T("")); ((CWnd*)m_pGrid)->Invalidate(FALSE); } else if (m_olePicture.GetPictureDispatch()) { m_olePicture.SetPictureDispatch(NULL); OnValueChanged(_T("")); ((CWnd*)m_pGrid)->Invalidate(FALSE); } }
BOOL GetPicture(HWND hwnd, IPictureDisp** ppPicture) { USES_CONVERSION; OPENFILENAME ofn; memset(&ofn, 0, sizeof OPENFILENAME); ofn.lStructSize = sizeof OPENFILENAME; ofn.lpstrFile = (TCHAR*) _alloca(_MAX_PATH * sizeof TCHAR); ofn.nMaxFile = _MAX_PATH; ofn.hwndOwner = hwnd; ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY; memset(ofn.lpstrFile, 0, _MAX_PATH * sizeof TCHAR); ofn.lpstrFilter = _T("所有图片文件\0*.bmp;*.dib;*.gif;*.jpg;*.wmf;*.emf;*.ico;*.cur\0") _T("位图 (*.bmp;*.dib)\0*.bmp;*.dib\0") _T("GIF 图像 (*.gif)\0*.gif\0") _T("JPEG 图像 (*.jpg)\0*.jpg\0") _T("元文件 (*.wmf;*.emf)\0*.wmf;*.emf\0") _T("Icons (*.ico;*.cur)\0*.ico;*.cur\0") _T("所有文件(*.*)\0*.*\0"); ofn.lpstrTitle = _T("加载图片"); if (GetOpenFileName(&ofn)) { CComBSTR bstr(ofn.lpstrFile); if (*ppPicture) (*ppPicture)->Release(); HRESULT hr = OleLoadPicturePath(bstr.m_str, 0, 0, 0, IID_IDispatch, (void**)ppPicture); return TRUE; } return FALSE; }
////////////////////////////////////////////////////////////////////////// //函数:BuildTexture() //参数:szPathName纹理路径,纹理ID //功能:加载纹理 ////////////////////////////////////////////////////////////////////////// bool Menu::BuildTexture(char *szPathName, GLuint &texid) { HDC hdcTemp; // The DC To Hold Our Bitmap HBITMAP hbmpTemp; // Holds The Bitmap Temporarily IPicture *pPicture; // IPicture Interface OLECHAR wszPath[MAX_PATH+1]; // Full Path To Picture (WCHAR) char szPath[MAX_PATH+1]; // Full Path To Picture long lWidth; // Width In Logical Units long lHeight; // Height In Logical Units long lWidthPixels; // Width In Pixels long lHeightPixels; // Height In Pixels GLint glMaxTexDim ; // Holds Maximum Texture Size if (strstr(szPathName, "http://")) // If PathName Contains http:// Then... { strcpy(szPath, szPathName); // Append The PathName To szPath } else // Otherwise... We Are Loading From A File { GetCurrentDirectory(MAX_PATH, szPath); // Get Our Working Directory strcat(szPath, "\\Image\\"); //strcat(szPath, "\\"); // Append "\" After The Working Directory strcat(szPath, szPathName); // Append The PathName } MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH); // Convert From ASCII To Unicode HRESULT hr = OleLoadPicturePath(wszPath, 0, 0, 0, IID_IPicture, (void**)&pPicture); if(FAILED(hr)) // If Loading Failed return FALSE; // Return False HDC tempDC=GetDC(0); hdcTemp = CreateCompatibleDC(tempDC); // Create The Windows Compatible Device Context if(!hdcTemp) // Did Creation Fail? { pPicture->Release(); // Decrements IPicture Reference Count return FALSE; // Return False (Failure) } ReleaseDC(NULL,tempDC); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTexDim); // Get Maximum Texture Size Supported pPicture->get_Width(&lWidth); // Get IPicture Width (Convert To Pixels) lWidthPixels = MulDiv(lWidth, GetDeviceCaps(hdcTemp, LOGPIXELSX), 2540); pPicture->get_Height(&lHeight); // Get IPicture Height (Convert To Pixels) lHeightPixels = MulDiv(lHeight, GetDeviceCaps(hdcTemp, LOGPIXELSY), 2540); // Resize Image To Closest Power Of Two if (lWidthPixels <= glMaxTexDim) // Is Image Width Less Than Or Equal To Cards Limit lWidthPixels = 1 << (int)floor((log((double)lWidthPixels)/log(2.0f)) + 0.5f); else // Otherwise Set Width To "Max Power Of Two" That The Card Can Handle lWidthPixels = glMaxTexDim; if (lHeightPixels <= glMaxTexDim) // Is Image Height Greater Than Cards Limit lHeightPixels = 1 << (int)floor((log((double)lHeightPixels)/log(2.0f)) + 0.5f); else // Otherwise Set Height To "Max Power Of Two" That The Card Can Handle lHeightPixels = glMaxTexDim; // Create A Temporary Bitmap BITMAPINFO bi = {0}; // The Type Of Bitmap We Request DWORD *pBits = 0; // Pointer To The Bitmap Bits bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // Set Structure Size bi.bmiHeader.biBitCount = 32; // 32 Bit bi.bmiHeader.biWidth = lWidthPixels; // Power Of Two Width bi.bmiHeader.biHeight = lHeightPixels; // Make Image Top Up (Positive Y-Axis) bi.bmiHeader.biCompression = BI_RGB; // RGB Encoding bi.bmiHeader.biPlanes = 1; // 1 Bitplane // Creating A Bitmap This Way Allows Us To Specify Color Depth And Gives Us Imediate Access To The Bits hbmpTemp = CreateDIBSection(hdcTemp, &bi, DIB_RGB_COLORS, (void**)&pBits, 0, 0); if(!hbmpTemp) // Did Creation Fail? { DeleteDC(hdcTemp); // Delete The Device Context pPicture->Release(); // Decrements IPicture Reference Count return FALSE; // Return False (Failure) } HGDIOBJ old; old=SelectObject(hdcTemp, hbmpTemp); // Select Handle To Our Temp DC And Our Temp Bitmap Object // Render The IPicture On To The Bitmap pPicture->Render(hdcTemp, 0, 0, lWidthPixels, lHeightPixels, 0, lHeight, lWidth, -lHeight, 0); // Convert From BGR To RGB Format And Add An Alpha Value Of 255 for(long i = 0; i < lWidthPixels * lHeightPixels; i++) // Loop Through All Of The Pixels { BYTE* pPixel = (BYTE*)(&pBits[i]); // Grab The Current Pixel BYTE temp = pPixel[0]; // Store 1st Color In Temp Variable (Blue) pPixel[0] = pPixel[2]; // Move Red Value To Correct Position (1st) pPixel[2] = temp; // Move Temp Value To Correct Blue Position (3rd) // This Will Make Any Black Pixels, Completely Transparent (You Can Hardcode The Value If You Wish) if ((pPixel[0]==0) && (pPixel[1]==0) && (pPixel[2]==0)) // Is Pixel Completely Black pPixel[3] = 0; // Set The Alpha Value To 0 else // Otherwise pPixel[3] = 255; // Set The Alpha Value To 255 } glGenTextures(1, &texid); // Create The Texture // Typical Texture Generation Using Data From The Bitmap glBindTexture(GL_TEXTURE_2D, texid); // Bind To The Texture ID glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // (Modify This For The Type Of Filtering You Want) glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // (Modify This For The Type Of Filtering You Want) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lWidthPixels, lHeightPixels, 0, GL_RGBA, GL_UNSIGNED_BYTE, pBits); // (Modify This If You Want Mipmaps) SelectObject(hdcTemp,old); DeleteObject(hbmpTemp); // Delete The Object DeleteDC(hdcTemp); // Delete The Device Context pPicture->Release(); // Decrements IPicture Reference Count return TRUE; // Return True (All Good) }
//==================================================================================== //= //= Function Name: LoadPictureIPicture //= //= Parameters : pcImage - the descriptor to load the image into //= szFilename - the path of the image file to load from //= //= Returns : TRUE if successful, FALSE otherwise //= //= Description : Loads BMP, EMF, JPG, ICO, WMF, GIF files into a texture descriptor //= by leveraging the power of Windows IPicture routines and OLE //= //==================================================================================== BOOL LoadPictureIPicture(CImage *pcImage, char *szFilename) { HDC hdcTemp; // The DC To Hold Our Bitmap HBITMAP hbmpTemp; // Holds The Bitmap Temporarily IPicture *pPicture; // IPicture Interface OLECHAR wszPath[MAX_PATH + 1]; // Full Path To Picture (WCHAR) long lWidth; // Width In Logical Units long lHeight; // Height In Logical Units long lWidthPixels; // Width In Pixels long lHeightPixels; // Height In Pixels HRESULT hr; short sType; DWORD dwAttributes; //---------------------------------------------------------------------------------------- // Convert From ASCII To Unicode and load the picture path //---------------------------------------------------------------------------------------- MultiByteToWideChar(CP_ACP, 0, szFilename, -1, wszPath, MAX_PATH); hr = OleLoadPicturePath(wszPath, 0, 0, 0, IID_IPicture, (void**)&pPicture); if(FAILED(hr)) { return FALSE; } hdcTemp = CreateCompatibleDC(GetDC(0)); if(!hdcTemp) { pPicture->Release(); return FALSE; } //---------------------------------------------------------------------------------------- // get the pixel dimensions of the image //---------------------------------------------------------------------------------------- pPicture->get_Attributes(&dwAttributes); pPicture->get_Type(&sType); pPicture->get_Width(&lWidth); lWidthPixels = MulDiv(lWidth, GetDeviceCaps(hdcTemp, LOGPIXELSX), 2540); pPicture->get_Height(&lHeight); lHeightPixels = MulDiv(lHeight, GetDeviceCaps(hdcTemp, LOGPIXELSY), 2540); //---------------------------------------------------------------------------------------- // Create A Temporary Bitmap //---------------------------------------------------------------------------------------- BITMAPINFO bi = {0}; // The Type Of Bitmap We Request unsigned int* pBits = NULL; // Pointer To The Bitmap Bits bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // Set Structure Size bi.bmiHeader.biBitCount = 32; // 32 Bit bi.bmiHeader.biWidth = lWidthPixels; // Power Of Two Width bi.bmiHeader.biHeight = lHeightPixels; // Make Image Top Up (Positive Y-Axis) bi.bmiHeader.biCompression = BI_RGB; // RGB Encoding bi.bmiHeader.biPlanes = 1; // 1 Bitplane hbmpTemp = CreateDIBSection(hdcTemp, &bi, DIB_RGB_COLORS, (void**)&pBits, 0, 0); if(!hbmpTemp) // Did Creation Fail? { DeleteDC(hdcTemp); // Delete The Device Context pPicture->Release(); // Decrements IPicture Reference Count return FALSE; // Return False (Failure) } SelectObject(hdcTemp, hbmpTemp); // Select Handle To Our Temp DC And Our Temp Bitmap Object //---------------------------------------------------------------------------------------- // Render The IPicture On To The Bitmap //---------------------------------------------------------------------------------------- pPicture->Render(hdcTemp, 0, 0, lWidthPixels, lHeightPixels, 0, lHeight, lWidth, -lHeight, 0); //---------------------------------------------------------------------------------------- // Copy the pixels to our texture descriptor whilst // Converting from BGR To RGB format and adding alpha of 255 //---------------------------------------------------------------------------------------- int x, y; unsigned int iAlpha; BOOL bNonZeroAlpha; CImage cImageImport; int i; CImageCopier cCopier; bNonZeroAlpha = FALSE; for (y = 0; y < lHeightPixels; y++) { for (x = 0; x < lWidthPixels; x++) { unsigned int iPixel = pBits[(x + (lHeightPixels - y - 1) * lWidthPixels)]; iAlpha = iPixel & 0xff000000; if (iAlpha != 0) { bNonZeroAlpha = TRUE; break; } } } //---------------------------------------------------------------------------------------- // setup the texture descriptor //---------------------------------------------------------------------------------------- // NOTE: does not set the unique ID correctly if (bNonZeroAlpha) { pcImage->Init(lWidthPixels, lHeightPixels, PT_uchar, IMAGE_DIFFUSE_RED, IMAGE_DIFFUSE_GREEN, IMAGE_DIFFUSE_BLUE, IMAGE_OPACITY, CHANNEL_ZERO); cImageImport.Init(lWidthPixels, lHeightPixels, pBits, PT_uchar, IMAGE_DIFFUSE_BLUE, IMAGE_DIFFUSE_GREEN, IMAGE_DIFFUSE_RED, IMAGE_OPACITY, CHANNEL_ZERO); cCopier.Init(&cImageImport, pcImage); for (i = 0; i < lHeightPixels; i++) { cImageImport.SetData(&pBits[(lHeightPixels - 1 - i) * lWidthPixels]); cCopier.Copy(0, i, 0, 0, lWidthPixels, 1); } //cCopier.Copy(0, 0, NULL); cCopier.Kill(); cImageImport.Kill(); } else { pcImage->Init(lWidthPixels, lHeightPixels, PT_uchar, IMAGE_DIFFUSE_RED, IMAGE_DIFFUSE_GREEN, IMAGE_DIFFUSE_BLUE, CHANNEL_ZERO); cImageImport.Init(lWidthPixels, lHeightPixels, pBits, PT_uchar, IMAGE_DIFFUSE_BLUE, IMAGE_DIFFUSE_GREEN, IMAGE_DIFFUSE_RED, IMAGE_IGNORED, CHANNEL_ZERO); cCopier.Init(&cImageImport, pcImage); for (i = 0; i < lHeightPixels; i++) { cImageImport.SetData(&pBits[(lHeightPixels - 1 - i) * lWidthPixels]); cCopier.Copy(0, i, 0, 0, lWidthPixels, 1); } cCopier.Kill(); cImageImport.Kill(); } DeleteObject(hbmpTemp); // Delete The Object DeleteDC(hdcTemp); // Delete The Device Context pPicture->Release(); // Decrements IPicture Reference Count return TRUE; // Return True (All Good) }
CTextureLoader::sRgbResult CTextureLoader::readPixels(char *file) { sRgbResult rgbResult; if (!file) { return rgbResult; } HDC hdcTemp; HBITMAP hbmpTemp; IPicture *pPicture; OLECHAR wszPath[MAX_PATH+1]; char szPath[MAX_PATH+1]; long lWidth; long lHeight; long lWidthPixels; long lHeightPixels; GLint glMaxTexDim ; if (strstr(file, "http://")) { strcpy(szPath, file); } else { if (strstr(file,":")==NULL) { GetCurrentDirectory(MAX_PATH, szPath); strcat(szPath, "\\"); strcat(szPath, file); } else { strcpy(szPath,file); } } MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH); HRESULT hr = OleLoadPicturePath(wszPath, 0, 0, 0, IID_IPicture, (void**)&pPicture); if(FAILED(hr)) { return rgbResult; } hdcTemp = CreateCompatibleDC(GetDC(0)); if(!hdcTemp) { pPicture->Release(); return rgbResult; } glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTexDim); pPicture->get_Width(&lWidth); lWidthPixels = MulDiv(lWidth, GetDeviceCaps(hdcTemp, LOGPIXELSX), 2540); pPicture->get_Height(&lHeight); lHeightPixels= MulDiv(lHeight, GetDeviceCaps(hdcTemp, LOGPIXELSY), 2540); // Resize Image To Closest Power Of Two if (lWidthPixels <= glMaxTexDim) { lWidthPixels = 1 << (int)floor((log((double)lWidthPixels)/log(2.0f)) + 0.5f); } else { lWidthPixels = glMaxTexDim; } if (lHeightPixels <= glMaxTexDim) { lHeightPixels = 1 << (int)floor((log((double)lHeightPixels)/log(2.0f)) + 0.5f); } else { lHeightPixels = glMaxTexDim; } // Create A Temporary Bitmap BITMAPINFO bi = {0}; DWORD *pBits = 0; bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biWidth = lWidthPixels; bi.bmiHeader.biHeight = lHeightPixels; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biPlanes = 1; hbmpTemp = CreateDIBSection(hdcTemp, &bi, DIB_RGB_COLORS, (void**)&pBits, 0, 0); if(!hbmpTemp) { DeleteDC(hdcTemp); pPicture->Release(); return rgbResult; } SelectObject(hdcTemp, hbmpTemp); pPicture->Render(hdcTemp, 0, 0, lWidthPixels, lHeightPixels, 0, lHeight, lWidth, -lHeight, 0); rgbResult.resetSize(lWidthPixels); for(long i = 0; i < lWidthPixels * lHeightPixels; i++) { BYTE* pPixel = (BYTE*)(&pBits[i]); BYTE temp = pPixel[0]; pPixel[0] = pPixel[2]; pPixel[2] = temp; rgbResult.rgb[i]=sRgbPixel(pPixel); } return rgbResult; }
CTextureLoader::sLoaderResult CTextureLoader::buildTexture(const char *file, GLuint &texture, bool trans, GLint texture_filter, bool auto_transparent, GLubyte R, GLubyte G, GLubyte B, bool full_path) { sLoaderResult lr; if (!file) { return lr; } HDC hdcTemp; HBITMAP hbmpTemp; IPicture *pPicture; OLECHAR wszPath[MAX_PATH+1]; char szPath[MAX_PATH+1]; long lWidth; long lHeight; long lWidthPixels; long lHeightPixels; GLint glMaxTexDim ; if (strstr(file, "http://")) { strcpy(szPath, file); } else { if (strstr(file,":")==NULL) { GetCurrentDirectory(MAX_PATH, szPath); strcat(szPath, "\\"); strcat(szPath, file); } else { strcpy(szPath,file); } } MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH); HRESULT hr = OleLoadPicturePath(wszPath, 0, 0, 0, IID_IPicture, (void**)&pPicture); if(FAILED(hr)) { return lr; } hdcTemp = CreateCompatibleDC(GetDC(0)); if(!hdcTemp) { pPicture->Release(); return lr; } glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTexDim); pPicture->get_Width(&lWidth); lWidthPixels = MulDiv(lWidth, GetDeviceCaps(hdcTemp, LOGPIXELSX), 2540); pPicture->get_Height(&lHeight); lHeightPixels= MulDiv(lHeight, GetDeviceCaps(hdcTemp, LOGPIXELSY), 2540); lr.texture_dimensions.x=lWidthPixels; lr.texture_dimensions.y=lHeightPixels; // Resize Image To Closest Power Of Two if (lWidthPixels <= glMaxTexDim) { lWidthPixels = 1 << (int)floor((log((double)lWidthPixels)/log(2.0f)) + 0.5f); } else { lWidthPixels = glMaxTexDim; } if (lHeightPixels <= glMaxTexDim) { lHeightPixels = 1 << (int)floor((log((double)lHeightPixels)/log(2.0f)) + 0.5f); } else { lHeightPixels = glMaxTexDim; } // Create A Temporary Bitmap BITMAPINFO bi = {0}; DWORD *pBits = 0; bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biWidth = lWidthPixels; bi.bmiHeader.biHeight = lHeightPixels; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biPlanes = 1; hbmpTemp = CreateDIBSection(hdcTemp, &bi, DIB_RGB_COLORS, (void**)&pBits, 0, 0); if(!hbmpTemp) { DeleteDC(hdcTemp); pPicture->Release(); return lr; } SelectObject(hdcTemp, hbmpTemp); pPicture->Render(hdcTemp, 0, 0, lWidthPixels, lHeightPixels, 0, lHeight, lWidth, -lHeight, 0); bool first=false; GLuint r,g,b; for(long i = 0; i < lWidthPixels * lHeightPixels; i++) { BYTE* pPixel = (BYTE*)(&pBits[i]); BYTE temp = pPixel[0]; pPixel[0] = pPixel[2]; pPixel[2] = temp; if (!first) { r=pPixel[0]; g=pPixel[1]; b=pPixel[2]; first=true; } if (trans) { if (auto_transparent) { if ((pPixel[0]==r) && (pPixel[1]==g) && (pPixel[2]==b)) { pPixel[3]=0; } else { pPixel[3]=255; } } else { if ((pPixel[0]==R) && (pPixel[1]==G) && (pPixel[2]==B)) { pPixel[3]=0; } else { pPixel[3]=255; } } } else { pPixel[3]=255; } } glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); /*glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,texture_filter); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,texture_filter); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lWidthPixels, lHeightPixels, 0, GL_RGBA, GL_UNSIGNED_BYTE, pBits);*/ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, 4, lWidthPixels, lHeightPixels, GL_RGBA, GL_UNSIGNED_BYTE, pBits); DeleteObject(hbmpTemp); DeleteDC(hdcTemp); pPicture->Release(); lr.done=true; return lr; }
// load an image from file. The supported filetypes depend on the plattform bool LoadImageFromFile(const char *filename, CByteImage *pImage) { HDC hdcTemp; // The DC To Hold Our Bitmap HBITMAP hbmpTemp; // Holds The Bitmap Temporarily IPicture *pPicture; // IPicture Interface OLECHAR wszPath[MAX_PATH+1]; // Full Path To Picture (WCHAR) long lWidth; // Width In Logical Units long lHeight; // Height In Logical Units long lWidthPixels; // Width In Pixels long lHeightPixels; // Height In Pixels MultiByteToWideChar(CP_ACP, 0, filename, -1, wszPath, MAX_PATH); // Convert From ASCII To Unicode HRESULT hr = OleLoadPicturePath(wszPath, 0, 0, 0, IID_IPicture, (void**)&pPicture); if(FAILED(hr)) // If Loading Failed return false; // Return False hdcTemp = CreateCompatibleDC(GetDC(0)); // Create The Windows Compatible Device Context if(!hdcTemp) // Did Creation Fail? { pPicture->Release(); // Decrements IPicture Reference Count return false; // Return False (Failure) } pPicture->get_Width(&lWidth); // Get IPicture Width (Convert To Pixels) lWidthPixels = MulDiv(lWidth, GetDeviceCaps(hdcTemp, LOGPIXELSX), 2540); pPicture->get_Height(&lHeight); // Get IPicture Height (Convert To Pixels) lHeightPixels = MulDiv(lHeight, GetDeviceCaps(hdcTemp, LOGPIXELSY), 2540); // Create A Temporary Bitmap BITMAPINFO bi = {0}; // The Type Of Bitmap We Request DWORD *pBits = 0; // Pointer To The Bitmap Bits bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // Set Structure Size bi.bmiHeader.biBitCount = 32; // 32 Bit bi.bmiHeader.biWidth = lWidthPixels; // Power Of Two Width bi.bmiHeader.biHeight = lHeightPixels; // Make Image Top Up (Positive Y-Axis) bi.bmiHeader.biCompression = BI_RGB; // RGB Encoding bi.bmiHeader.biPlanes = 1; // 1 Bitplane // Creating A Bitmap This Way Allows Us To Specify Color Depth And Gives Us Imediate Access To The Bits hbmpTemp = CreateDIBSection(hdcTemp, &bi, DIB_RGB_COLORS, (void**)&pBits, 0, 0); if(!hbmpTemp) // Did Creation Fail? { DeleteDC(hdcTemp); // Delete The Device Context pPicture->Release(); // Decrements IPicture Reference Count return false; // Return False (Failure) } SelectObject(hdcTemp, hbmpTemp); // Select Handle To Our Temp DC And Our Temp Bitmap Object // Render The IPicture On To The Bitmap pPicture->Render(hdcTemp, 0, 0, lWidthPixels, lHeightPixels, 0, 0, lWidth, lHeight, 0); if (pImage->m_bOwnMemory) delete [] pImage->pixels; pImage->width = lWidthPixels; pImage->height = lHeightPixels; pImage->bytesPerPixel = 3; pImage->type = CByteImage::eRGB24; pImage->pixels = new unsigned char[pImage->bytesPerPixel * lWidthPixels*lHeightPixels]; pImage->m_bOwnMemory = true; unsigned char *output = pImage->pixels; // Convert From BGR To RGB Format And Add An Alpha Value Of 255 for(long i = 0; i < lWidthPixels * lHeightPixels; i++) // Loop Through All Of The Pixels { BYTE* pPixel = (BYTE*)(&pBits[i]); // Grab The Current Pixel output[3*i] = pPixel[2]; // Store 1st Color In Temp Variable (Blue) output[3*i + 1] = pPixel[1]; // Move Red Value To Correct Position (1st) output[3*i + 2] = pPixel[0]; // Move Temp Value To Correct Blue Position (3rd) } DeleteObject(hbmpTemp); // Delete The Object DeleteDC(hdcTemp); // Delete The Device Context pPicture->Release(); // Decrements IPicture Reference Count return true; }
static void test_OleLoadPicturePath(void) { static WCHAR emptyW[] = {0}; IPicture *pic; HRESULT hres; int i; char temp_path[MAX_PATH]; char temp_file[MAX_PATH]; WCHAR temp_fileW[MAX_PATH + 5] = {'f','i','l','e',':','/','/','/'}; HANDLE file; DWORD size; WCHAR *ptr; const struct { LPOLESTR szURLorPath; REFIID riid; IPicture **pic; } invalid_parameters[] = { {NULL, NULL, NULL}, {NULL, NULL, &pic}, {NULL, &IID_IPicture, NULL}, {NULL, &IID_IPicture, &pic}, {emptyW, NULL, NULL}, {emptyW, &IID_IPicture, NULL}, }; for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++) { pic = (IPicture *)0xdeadbeef; hres = OleLoadPicturePath(invalid_parameters[i].szURLorPath, NULL, 0, 0, invalid_parameters[i].riid, (void **)invalid_parameters[i].pic); ok(hres == E_INVALIDARG, "[%d] Expected OleLoadPicturePath to return E_INVALIDARG, got 0x%08x\n", i, hres); ok(pic == (IPicture *)0xdeadbeef, "[%d] Expected output pointer to be 0xdeadbeef, got %p\n", i, pic); } pic = (IPicture *)0xdeadbeef; hres = OleLoadPicturePath(emptyW, NULL, 0, 0, NULL, (void **)&pic); todo_wine ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */ broken(hres == E_UNEXPECTED) || /* NT4 */ broken(hres == E_OUTOFMEMORY), /* Win2k/Win2k3 */ "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres); ok(pic == NULL, "Expected the output interface pointer to be NULL, got %p\n", pic); pic = (IPicture *)0xdeadbeef; hres = OleLoadPicturePath(emptyW, NULL, 0, 0, &IID_IPicture, (void **)&pic); todo_wine ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */ broken(hres == E_UNEXPECTED) || /* NT4 */ broken(hres == E_OUTOFMEMORY), /* Win2k/Win2k3 */ "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres); ok(pic == NULL, "Expected the output interface pointer to be NULL, got %p\n", pic); /* Create a local temporary image file for testing. */ GetTempPathA(sizeof(temp_path), temp_path); GetTempFileNameA(temp_path, "bmp", 0, temp_file); file = CreateFileA(temp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(file, bmpimage, sizeof(bmpimage), &size, NULL); CloseHandle(file); MultiByteToWideChar(CP_ACP, 0, temp_file, -1, temp_fileW + 8, sizeof(temp_fileW)/sizeof(WCHAR) - 8); /* Try a normal DOS path. */ hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic); ok(hres == S_OK || broken(hres == E_UNEXPECTED), /* NT4 */ "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres); if (pic) IPicture_Release(pic); /* Try a DOS path with tacked on "file:". */ hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic); ok(hres == S_OK || broken(hres == E_UNEXPECTED), /* NT4 */ "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres); if (pic) IPicture_Release(pic); DeleteFileA(temp_file); /* Try with a nonexistent file. */ hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic); ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */ broken(hres == E_UNEXPECTED) || /* NT4 */ broken(hres == E_FAIL), /*Win2k */ "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres); hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic); ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */ broken(hres == E_UNEXPECTED) || /* NT4 */ broken(hres == E_FAIL), /* Win2k */ "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres); file = CreateFileA(temp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(file, bmpimage, sizeof(bmpimage), &size, NULL); CloseHandle(file); /* Try a "file:" URL with slash separators. */ ptr = temp_fileW + 8; while (*ptr) { if (*ptr == '\\') *ptr = '/'; ptr++; } hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic); ok(hres == S_OK || broken(hres == E_UNEXPECTED), /* NT4 */ "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres); if (pic) IPicture_Release(pic); DeleteFileA(temp_file); /* Try with a nonexistent file. */ hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic); ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */ broken(hres == E_UNEXPECTED) || /* NT4 */ broken(hres == E_FAIL), /* Win2k */ "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres); }