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

JPEG画像をビットマップとして読み込む

戻る


JPEG画像をビットマップとして読み込むには、次のような コードを使うとよい。

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include <stdio.h>

#ifdef __cplusplus
extern "C"
{
#endif
#define XMD_H
#include <jpeglib.h>
#include <jerror.h>
#ifdef __cplusplus
}
#endif

#pragma comment(lib, "libjpeg.lib")

HBITMAP LoadJpegAsBitmap(LPCSTR pszFileName)
{
    FILE *fp;
    struct jpeg_decompress_struct decomp;
    struct jpeg_error_mgr jerror;
    BITMAPINFO bi;
    LPBYTE lpBuf, pb;
    HBITMAP hbm;
    JSAMPARRAY buffer;
    INT row;
    
    fp = fopen(pszFileName, "rb");
    if (fp == NULL)
        return NULL;

    decomp.err = jpeg_std_error(&jerror);

    jpeg_create_decompress(&decomp);
    jpeg_stdio_src(&decomp, fp);

    jpeg_read_header(&decomp, TRUE);
    jpeg_start_decompress(&decomp);

    row = ((decomp.output_width * 3 + 3) & ~3);
    buffer = (*decomp.mem->alloc_sarray)((j_common_ptr)&decomp, JPOOL_IMAGE, 
                                         row, 1);

    ZeroMemory(&bi.bmiHeader, sizeof(BITMAPINFOHEADER));
    bi.bmiHeader.biSize         = sizeof(BITMAPINFOHEADER);
    bi.bmiHeader.biWidth        = decomp.output_width;
    bi.bmiHeader.biHeight       = decomp.output_height;
    bi.bmiHeader.biPlanes       = 1;
    bi.bmiHeader.biBitCount     = 24;
    bi.bmiHeader.biCompression  = BI_RGB;
    bi.bmiHeader.biSizeImage    = row * decomp.output_height;

    hbm = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void**)&lpBuf, NULL, 0);
    if (hbm == NULL)
    {
        jpeg_destroy_decompress(&decomp);
        fclose(fp);
        return NULL;
    }

    pb = lpBuf + row * decomp.output_height;
    while(decomp.output_scanline < decomp.output_height)
    {
        pb -= row;
        jpeg_read_scanlines(&decomp, buffer, 1);
        
        if (decomp.out_color_components == 1)
        {
            UINT i;
            LPBYTE p = (LPBYTE)buffer[0];
            for(i = 0; i < decomp.output_width; i++)
            {
                pb[3 * i + 0] = p[i];
                pb[3 * i + 1] = p[i];
                pb[3 * i + 2] = p[i];
            }
        }
        else if (decomp.out_color_components == 3)
        {
            CopyMemory(pb, buffer[0], row);
        }
        else
        {
            jpeg_destroy_decompress(&decomp);
            fclose(fp);
            DeleteObject(hbm);
            return NULL;
        }
    }
    
    SetDIBits(NULL, hbm, 0, decomp.output_height, lpBuf, &bi, DIB_RGB_COLORS);
    
    jpeg_finish_decompress(&decomp);
    jpeg_destroy_decompress(&decomp);

    fclose(fp);
    
    return hbm;
}

#ifdef UNITTEST
typedef struct tagBITMAPINFOEX
{
    BITMAPINFOHEADER bmiHeader;
    RGBQUAD          bmiColors[256];
} BITMAPINFOEX, FAR * LPBITMAPINFOEX;

BOOL SaveBitmapToFile(LPCTSTR pszFileName, HBITMAP hbm)
{
    ...
}

int main(void)
{
    HBITMAP hbm = LoadJpegAsBitmap("a.jpg");
    SaveBitmapToFile("a.bmp", hbm);
    return 0;
}
#endif  // def UNITTEST

なお、このコードをコンパイルするには、libjpegライブラリが必要だ。

ソース: loadjpeg.zip


戻る

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

inserted by FC2 system