c++使用std_image.c來加載jpg,png,gif等格式圖片


#include <windows.h>
#include <tchar.h>
#include <WindowsX.h>
HINSTANCE hInst;

#pragma comment(lib,"Msimg32.lib")
extern "C"
{
    extern unsigned char *stbi_load_from_memory(unsigned char const *buffer, int len, int *x, int *y,int *comp, int req_comp);
    extern void     stbi_image_free(void *retval_from_stbi_load);
};

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam);

int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE,LPTSTR,int nCmdShow)
{
    hInst = hInstance; // Store instance handle in our global variable

    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = hInstance;
    wcex.hIcon            = NULL;
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = (HBRUSH)(COLOR_BACKGROUND);
    wcex.lpszMenuName    = NULL;
    wcex.lpszClassName    = _T("std_image.c");
    wcex.hIconSm        = NULL;
    if(!RegisterClassEx(&wcex)) return FALSE;

    HWND hWnd = CreateWindow(_T("std_image.c"), _T("std_image.c"), WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

    DWORD dw = GetLastError();
    if (!hWnd)
    {
        return FALSE;
    }

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);    
    MSG msg;
    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_PAINT:
        {
            OnPaint(hWnd,wParam,lParam);
        }break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

LRESULT OnPaint(HWND hWnd,WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;            
    HDC hdc = BeginPaint(hWnd, &ps);
    HANDLE hFile = ::CreateFile(_T("test.png"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, \
        FILE_ATTRIBUTE_NORMAL, NULL);
    if( hFile == INVALID_HANDLE_VALUE ) return NULL;
    DWORD dwSize = ::GetFileSize(hFile, NULL);
    if( dwSize == 0 ) return NULL;

    DWORD dwRead = 0;
    LPBYTE pData = new BYTE[ dwSize ];
    ::ReadFile( hFile, pData, dwSize, &dwRead, NULL );
    ::CloseHandle( hFile );

    if( dwRead != dwSize ) {
        delete[] pData;
        return NULL;
    }

    LPBYTE pImage = NULL;
    int x,y,n;
    pImage = stbi_load_from_memory(pData, dwSize, &x, &y, &n, 4);
    delete[] pData;
    if( !pImage ) return NULL;

    BITMAPINFO bmi;
    ::ZeroMemory(&bmi, sizeof(BITMAPINFO));
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = x;
    bmi.bmiHeader.biHeight = -y;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biSizeImage = x * y * 4;

    bool bAlphaChannel = false;
    LPBYTE pDest = NULL;
    HBITMAP hBitmap = ::CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void**)&pDest, NULL, 0);
    if( !hBitmap ) return NULL;

//     for( int i = 0; i < x * y; i++ ) 
//     {
//         pDest[i*4 + 3] = pImage[i*4 + 3];
//         if( pDest[i*4 + 3] < 255 )//RGBA
//         {
//             pDest[i*4] = (BYTE)(DWORD(pImage[i*4 + 2])*pImage[i*4 + 3]/255);
//             pDest[i*4 + 1] = (BYTE)(DWORD(pImage[i*4 + 1])*pImage[i*4 + 3]/255);
//             pDest[i*4 + 2] = (BYTE)(DWORD(pImage[i*4])*pImage[i*4 + 3]/255); 
//             bAlphaChannel = true;
//         }
//         else // = 255
//         {
//             pDest[i*4] = pImage[i*4 + 2];
//             pDest[i*4 + 1] = pImage[i*4 + 1];
//             pDest[i*4 + 2] = pImage[i*4]; 
//         }
// 
//         if( *(DWORD*)(&pDest[i*4]) == 0 ) {
//             pDest[i*4] = (BYTE)0;
//             pDest[i*4 + 1] = (BYTE)0;
//             pDest[i*4 + 2] = (BYTE)0; 
//             pDest[i*4 + 3] = (BYTE)0;
//             bAlphaChannel = true;
//         }
//     }

    memcpy(pDest,pImage,bmi.bmiHeader.biSizeImage);
    stbi_image_free(pImage);

    HDC hMemdc = CreateCompatibleDC(hdc);
    SelectBitmap(hMemdc,hBitmap);

    BLENDFUNCTION ftn = { 0 };
    ftn.BlendOp = AC_SRC_OVER;                                                        // 目前只能設置這個值
    ftn.AlphaFormat = AC_SRC_ALPHA;                                                      // 也只能設置這個值
    ftn.BlendFlags = 0;                                                               // 必須為0
    ftn.SourceConstantAlpha = 255;                                                    // 指定源圖片的alpha

    AlphaBlend(hdc,0,0,x,y,hMemdc,0,0,x,y,ftn);
    EndPaint(hWnd, &ps);

    return 0;
}

20121030更正: 上面屏蔽代碼不能使用, 以下代碼替代

memcpy(pDest,pImage,bmi.bmiHeader.biSizeImage);

因為源碼說明 // if you set req_comp to 4, you will always get RGBA output, 所以我應該將其轉換成位圖的存儲格式BGRA, 上次沒有發現問題, 原因應該是測試的圖片是灰度圖片, RGB值是一樣的




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM