ソフトウェア開発 Win32プログラミング

ファイルからビットマップ画像を読み込む

戻る


ファイルからビットマップ画像を読み込みたい場合は、次のような関数を使うとよい。

#include <windows.h>
#include <stdlib.h>

typedef struct tagBITMAPINFOEX
{
    BITMAPINFOHEADER bmiHeader;
    RGBQUAD          bmiColors[256];
} BITMAPINFOEX, FAR * LPBITMAPINFOEX;
 
// トップダウンビットマップが読み込めない。
HBITMAP LoadBitmapFromFileCheap(LPCTSTR pszFileName)
{
#ifndef LR_LOADREALSIZE
#define LR_LOADREALSIZE 128
#endif
    return (HBITMAP)LoadImage(NULL, pszFileName, IMAGE_BITMAP,
        0, 0, LR_LOADREALSIZE | LR_LOADFROMFILE | LR_CREATEDIBSECTION);
}
 
// トップダウンビットマップが読み込める。
HBITMAP LoadBitmapFromFile(LPCTSTR pszFileName)
{
    HANDLE hFile;
    BITMAPFILEHEADER bf;
    BITMAPINFOEX bi;
    DWORD cb, cbImage;
    LPVOID pBits, pBits2;
    HDC hDC;
    HBITMAP hbm;
    DWORD dwError = 0;
 
#ifndef LR_LOADREALSIZE
#define LR_LOADREALSIZE 128
#endif
    hbm = (HBITMAP)LoadImage(NULL, pszFileName, IMAGE_BITMAP, 0, 0,
        LR_LOADFROMFILE | LR_LOADREALSIZE | LR_CREATEDIBSECTION);
    if (hbm != NULL)
        return hbm;
 
    hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
        return NULL;
 
    if (!ReadFile(hFile, &bf, sizeof(BITMAPFILEHEADER), &cb, NULL))
    {
        dwError = GetLastError();
        CloseHandle(NULL);
        SetLastError(dwError);
        return NULL;
    }
 
    pBits = NULL;
    if (bf.bfType == 0x4D42 && bf.bfReserved1 == 0 && bf.bfReserved2 == 0 &&
        bf.bfSize > bf.bfOffBits && bf.bfOffBits > sizeof(BITMAPFILEHEADER) &&
        bf.bfOffBits <= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOEX))
    {
        cbImage = bf.bfSize - bf.bfOffBits;
        pBits = HeapAlloc(GetProcessHeap(), 0, cbImage);
        if (pBits != NULL)
        {
            if (!ReadFile(hFile, &bi, bf.bfOffBits -
                          sizeof(BITMAPFILEHEADER), &cb, NULL) ||
                !ReadFile(hFile, pBits, cbImage, &cb, NULL))
            {
                dwError = GetLastError();
                HeapFree(GetProcessHeap(), 0, pBits);
                pBits = NULL;
            }
        }
        else
            dwError = GetLastError();
    }
    else
        dwError = ERROR_INVALID_DATA;
 
    CloseHandle(hFile);
 
    if (pBits == NULL)
    {
        SetLastError(dwError);
        return NULL;
    }
 
    hbm = CreateDIBSection(NULL, (BITMAPINFO*)&bi, DIB_RGB_COLORS,
                           &pBits2, NULL, 0);
    if (hbm != NULL)
    {
        if (!SetDIBits(NULL, hbm, 0, abs(bi.bmiHeader.biHeight),
                       pBits, (BITMAPINFO*)&bi, DIB_RGB_COLORS))
        {
            dwError = GetLastError();
            DeleteObject(hbm);
            hbm = NULL;
        }
    }
    else
        dwError = GetLastError();
 
    HeapFree(GetProcessHeap(), 0, pBits);
    SetLastError(dwError);
 
    return hbm;
}

LoadBitmapFromFileCheap関数は、LoadImage APIを利用した簡単な読み取りコード。だが、これは トップダウンビットマップ(BITMAPINFOHEADER構造体のbiHeightが負の値の 場合のビットマップ)を読み込めない。 LoadBitmapFromFile関数は、トップダウンビットマップも読み込める。

ソース: loadbmp.zip


戻る

©片山博文MZ
katayama.hirofumi.mz@gmail.com

inserted by FC2 system