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; 
        } 
    }

  • 相关阅读:
    还在使用golang 的map 做Json编码么?
    Golang 性能测试(2) 性能分析
    golang 性能测试 (1) 基准性能测试
    消息队列 NSQ 源码学习笔记 (五)
    消息队列 NSQ 源码学习笔记 (四)
    消息队列 NSQ 源码学习笔记 (三)
    消息队列 NSQ 源码学习笔记 (二)
    消息队列 NSQ 源码学习笔记 (一)
    你不知道的空格
    Supervisor 使用和进阶4 (Event 的使用)
  • 原文地址:https://www.cnblogs.com/lidabo/p/3284816.html
Copyright © 2011-2022 走看看