利用COM組件IPicture讀取jpg、gif、bmp圖片文件數據和顯示圖片的兩個函數

原文地址:http://www.cnblogs.com/zuollblog/archive/2010/04/21/1716983.html 

1.讀取圖片數據

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

函數功能,讀取pName指向的圖片文件的位圖數據

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
boolLoadImage(constchar*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標準碼
    HRESULThr = OleLoadPicturePath(wszPath, 0, 0, 0, IID_IPicture, (void**)&pPicture);
  
    if(FAILED(hr)) // 如果導入失敗
    {
        // 圖片載入失敗出錯信息
        MessageBox (HWND_DESKTOP,"圖片導入失敗!\n(TextureLoad Failed!)","Error", MB_OK | MB_ICONEXCLAMATION);
        returnFALSE;   // 返回 FALSE
    }
  
    hdcTemp = CreateCompatibleDC(GetDC(0));// 建立窗口設備描述表
    if(!hdcTemp)   // 建立失敗?
    {
        pPicture->Release();// 釋放IPicture
        // 圖片載入失敗出錯信息
        MessageBox (HWND_DESKTOP,"圖片導入失敗!\n(TextureLoad Failed!)","Error", MB_OK | MB_ICONEXCLAMATION);
        returnFALSE;       // 返回 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);
        returnFALSE;   // 返回 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 =newunsigned char[lWidthPixels * lHeightPixels * 4];
                // 循環遍歷所有的像素
    for(longi = 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
    returntrue;       // 返回 TRUE
}

2.顯示圖片

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

函數功能,讀取lpImageFile指向的圖片文件,並且顯示以nScrWidth*nScrHeight顯示在hWnd中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
HRESULTShowPicture(CString lpImageFile, HWNDhWnd, intnScrWidth, intnScrHeight)
{
    HDChDC_Temp=::GetDC(hWnd);
    IPicture *pPic;
    IStream *pStm;
    BOOLbResult;
    HANDLEhFile=NULL;
    DWORDdwFileSize,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)
            returnE_FAIL;
    }
    else
    {
        returnE_FAIL;
    }
    //分配全局存儲空間
    HGLOBALhGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
    LPVOIDpvData = NULL;
    if(hGlobal == NULL)
    {
        AfxMessageBox(_T("圖片分配內存出錯!"));
        returnE_FAIL;
    }
    if((pvData = GlobalLock(hGlobal)) == NULL)//鎖定分配內存塊
    {
        AfxMessageBox(_T("內存塊鎖定出問題!"));
        returnE_FAIL;
    }
    ReadFile(hFile, pvData, dwFileSize, &dwByteRead, NULL);//把文件讀入內存緩衝區
    GlobalUnlock(hGlobal);
    if(CreateStreamOnHGlobal(hGlobal, TRUE, &pStm) != S_OK)
    {
        AfxMessageBox(_T("流初始化失敗!"));
        returnE_FAIL;
    }
    //裝入圖形文件
    bResult=OleLoadPicture(pStm,dwFileSize,TRUE,IID_IPicture,(LPVOID*)&pPic);
    if(FAILED(bResult))
    {
        AfxMessageBox(_T("圖形文件裝載出錯!"));
        returnE_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))
    {
        returnS_OK;
    }
    else
    {
        AfxMessageBox(_T("圖形文件裝載出錯!"));
        returnE_FAIL;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章