zoukankan      html  css  js  c++  java
  • 利用COM组件IPicture读取jpg、gif、bmp图片文件数据和显示图片

    1.读取图片数据

    函数原型:bool LoadImage(const char *pName, unsigned char *pBitData);

    函数功能,读取pName指向的图片文件的位图数据

    bool LoadImage(const char *pName, unsigned char *pBitData) 
    { 
        HDC     hdcTemp; // DC用来保存位图 
        HBITMAP     hbmpTemp; // 保存临时位图 
        IPicture    *pPicture; // 定义IPicture Interface 
        OLECHAR     wszPath[MAX_PATH+1]; // 图片的完全路径 
        char        szPath[MAX_PATH+1]; // 图片的完全路径 
        long        lWidth; // 图像宽度 
        long        lHeight; // 图像高度 
        long        lWidthPixels; // 图像的宽带(以像素为单位) 
        long        lHeightPixels; // 图像的高带(以像素为单位) 
        GLint       glMaxTexDim ; // 保存纹理的最大尺寸 
      
        if (strstr(pName, "http://"))   // 如果路径包含 http:// 则… 
        { 
            strcpy(szPath, pName);  // 把路径拷贝到 szPath 
        } 
        else    // 否则从文件导入图片 
        { 
            GetCurrentDirectory(MAX_PATH, szPath);  // 取得当前路径 
            strcat(szPath, "\");           // 添加字符"" 
            strcat(szPath, pName);          // 添加图片的相对路径 
        } 
      
        MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH);  // 把ASCII码转化为Unicode标准码 
        HRESULT hr = OleLoadPicturePath(wszPath, 0, 0, 0, IID_IPicture, (void**)&pPicture); 
      
        if(FAILED(hr))  // 如果导入失败 
        { 
            // 图片载入失败出错信息 
            MessageBox (HWND_DESKTOP, "图片导入失败! (TextureLoad Failed!)", "Error", MB_OK | MB_ICONEXCLAMATION); 
            return FALSE;   // 返回 FALSE 
        } 
      
        hdcTemp = CreateCompatibleDC(GetDC(0)); // 建立窗口设备描述表 
        if(!hdcTemp)    // 建立失败? 
        { 
            pPicture->Release(); // 释放IPicture 
            // 图片载入失败出错信息 
            MessageBox (HWND_DESKTOP, "图片导入失败! (TextureLoad Failed!)", "Error", MB_OK | MB_ICONEXCLAMATION); 
            return FALSE;       // 返回 FALSE 
        } 
      
        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTexDim);   // 取得支持的纹理最大尺寸 
        pPicture->get_Width(&lWidth);    // 取得IPicture 宽度 (转换为Pixels格式) 
        lWidthPixels = MulDiv(lWidth, GetDeviceCaps(hdcTemp, LOGPIXELSX), 2540); 
        pPicture->get_Height(&lHeight);  // 取得IPicture 高度 (转换为Pixels格式) 
        lHeightPixels = MulDiv(lHeight, GetDeviceCaps(hdcTemp, LOGPIXELSY), 2540); 
      
        // 调整图片到最好的效果 
        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; // 建立一个临时位图 
        BITMAPINFO  bi = {0};     // 位图的类型 
        DWORD       *pBits = 0; // 指向位图Bits的指针 
      
        bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // 设置结构大小 
        bi.bmiHeader.biBitCount = 32;                // 32 位 
        bi.bmiHeader.biWidth    = lWidthPixels; // 宽度像素值 
        bi.bmiHeader.biHeight   = lHeightPixels;    // 高度像素值 
        bi.bmiHeader.biCompression  = BI_RGB;            // RGB 格式 
        bi.bmiHeader.biPlanes   = 1;                    // 一个位平面 
      
        // 建立一个位图这样我们可以指定颜色和深度 并访问每位的值 
        hbmpTemp = CreateDIBSection(hdcTemp, &bi, DIB_RGB_COLORS, (void**)&pBits, 0, 0); 
      
        if(!hbmpTemp)   // 建立失败? 
        { 
            DeleteDC(hdcTemp);   // 删除设备描述表 
            pPicture->Release();   // 释放IPicture 
            // 图片载入失败出错信息 
            MessageBox (HWND_DESKTOP, "图片导入失败! (TextureLoad Failed!)", "Error", MB_OK | MB_ICONEXCLAMATION); 
            return FALSE;   // 返回 FALSE 
        }   
        SelectObject(hdcTemp, hbmpTemp); //选择临时DC句柄和临时位图对象 
      
        // 在位图上绘制IPicture 
        pPicture->Render(hdcTemp, 0, 0, lWidthPixels, lHeightPixels, 0, lHeight, lWidth, -lHeight, 0); 
      
        // 将BGR转换为RGB 将ALPHA值设为255 
        width = lWidthPixels; height = lHeightPixels; 
        pBitData = new unsigned char[lWidthPixels * lHeightPixels * 4]; 
                    // 循环遍历所有的像素 
        for(long i = 0; i < lWidthPixels * lHeightPixels; i++)   
        { 
            BYTE* pPixel      = (BYTE*)(&pBits[i]);  // 获取当前像素 
            pBitData[i*4]     = pPixel[2]; 
            pBitData[i*4+1] = pPixel[1]; 
            pBitData[i*4+2] = pPixel[0]; 
            pBitData[i*4+3] = 255; 
        } 
        DeleteObject(hbmpTemp); // 删除对象 
        DeleteDC(hdcTemp);  // 删除设备描述表 
        pPicture->Release(); // 释放 IPicture 
        return true;        // 返回 TRUE 
    } 
    2.显示图片

    函数原型:HRESULT ShowPicture(CString lpImageFile, HWND hWnd, int nScrWidth, int nScrHeight)

    函数功能,读取lpImageFile指向的图片文件,并且显示以nScrWidth*nScrHeight显示在hWnd中

    HRESULT ShowPicture(CString lpImageFile, HWND hWnd, int nScrWidth, int nScrHeight)
    { 
        HDC hDC_Temp=::GetDC(hWnd); 
        IPicture *pPic; 
        IStream *pStm; 
        BOOL bResult; 
        HANDLE hFile=NULL; 
        DWORD dwFileSize,dwByteRead; 
        //打开硬盘中的图形文件 
        hFile=CreateFile(lpImageFile,GENERIC_READ, 
            FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); 
        if (hFile!=INVALID_HANDLE_VALUE) 
        { 
            dwFileSize=GetFileSize(hFile,NULL);//获取文件字节数 
            if (dwFileSize==0xFFFFFFFF) 
                return E_FAIL; 
        } 
        else 
        { 
            return E_FAIL; 
        } 
        //分配全局存储空间 
        HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize); 
        LPVOID pvData = NULL; 
        if (hGlobal == NULL) 
        { 
            AfxMessageBox(_T("图片分配内存出错!")); 
            return E_FAIL; 
        } 
        if ((pvData = GlobalLock(hGlobal)) == NULL)//锁定分配内存块 
        { 
            AfxMessageBox(_T("内存块锁定出问题!")); 
            return E_FAIL; 
        } 
        ReadFile(hFile, pvData, dwFileSize, &dwByteRead, NULL);//把文件读入内存缓冲区 
        GlobalUnlock(hGlobal); 
        if(CreateStreamOnHGlobal(hGlobal, TRUE, &pStm) != S_OK) 
        { 
            AfxMessageBox(_T("流初始化失败!")); 
            return E_FAIL; 
        } 
        //装入图形文件 
        bResult=OleLoadPicture(pStm,dwFileSize,TRUE,IID_IPicture,(LPVOID*)&pPic); 
        if(FAILED(bResult)) 
        { 
            AfxMessageBox(_T("图形文件装载出错!")); 
            return E_FAIL; 
        } 
        OLE_XSIZE_HIMETRIC hmWidth;//图片的真实宽度 
        OLE_YSIZE_HIMETRIC hmHeight;//图片的真实高度 
        pPic->get_Width(&hmWidth); 
        pPic->get_Height(&hmHeight); 
        //将图形输出到屏幕上 
        bResult=pPic->Render(hDC_Temp,0,0,nScrWidth,nScrHeight, 
            0,hmHeight,hmWidth,-hmHeight,NULL); 
        CloseHandle(hFile);//关闭打开的文件 
      
        pPic->Release(); 
        // Free memory. 
        GlobalFree(hGlobal); 
        if (SUCCEEDED(bResult)) 
        { 
            return S_OK; 
        } 
        else 
        { 
            AfxMessageBox(_T("图形文件装载出错!")); 
            return E_FAIL; 
        } 
    }

  • 相关阅读:
    Java 基础知识(五)
    Java 基础知识(四)
    Java 基础知识(三)
    Java 基础知识(二)
    python 默认参数潜在的问题
    python中统计计数的几种方法和Counter的介绍
    简单的总结一下到底什么是python
    python中的__solots__方法
    python中生成器和迭代器以及可迭代对象的区别
    游览器访问一个网址的全过程
  • 原文地址:https://www.cnblogs.com/lidabo/p/3284816.html
Copyright © 2011-2022 走看看