分享

利用COM组件IPicture读取jpg、gif、bmp图片文件数据和显示图片的两个函数

 GANG8285 2015-08-21
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, "图片导入失败!\n(TextureLoad Failed!)", "Error", MB_OK | MB_ICONEXCLAMATION);
        return FALSE;   // 返回 FALSE
    }
    hdcTemp = CreateCompatibleDC(GetDC(0)); // 建立窗口设备描述表
    if(!hdcTemp)    // 建立失败?
    {
        pPicture->Release(); // 释放IPicture
        // 图片载入失败出错信息
        MessageBox (HWND_DESKTOP, "图片导入失败!\n(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, "图片导入失败!\n(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
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约