FC2ブログ

ホーム > DIBファイルフォーマット > DIBファイルの読み込み

DIBファイルの読み込み



DIBファイル(拡張子bmp)は、デバイス独立ビットマップDIB)の形で格納されおり、以下のような構造をしています。

  1. BITMAPFILEHEADER構造体
  2. BITMAPINFO構造体
  3. ピクセルデータ




今回は32ビットアルファDIBを作成するためにBITMAPV5HEADER構造体を使用します。
そのためにプロジェクト内の「stdafx.h」の内容のうち、下記の赤字部分を訂正してください。

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently


#pragma once

#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#endif

// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.

#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
#define WINVER 0x0500 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. ←0x0400から、0x0500に変更してください。
#endif

#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
#define _WIN32_WINNT 0x0500 // Change this to the appropriate value to target Windows 2000 or later. ←0x0400から、0x0500に変更してください。
#endif

#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0500 // Change this to the appropriate value to target Windows Me or later. ←0x0410から、0x0500に変更してください。
#endif

#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
#define _WIN32_IE 0x0500 // Change this to the appropriate value to target IE 5.0 or later. ←0x0400から、0x0500に変更してください。
#endif

#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit

#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions



ビットマップバイト幅を算出するためのマクロ定義です。

//ビットマップバイト幅の算出マクロ
#ifndef WIDTHBYTES
#define WIDTHBYTES(bits) (((bits)+31)/32*4)
#endif//WIDTHBYTES


DIBファイル を開いて、_DIBStreamIn関数を呼び出します。

//DIBファイルの読み込み
HBITMAP __stdcall _LoadDIB(LPCTSTR lpszFileName,LPDWORD lpdwCompression)
{
CFile infile;
if (!infile.Open(lpszFileName,CFile::modeRead)) return FALSE;
HBITMAP hBitmap=_DIBStreamIn(&infile,lpdwCompression);
infile.Close();
if (!hBitmap) return FALSE;
return hBitmap;
}


DIBファイルを読み込んでDIBを作成します。

//DIBファイルストリームの読み込み
HBITMAP __stdcall _DIBStreamIn(CFile* infile,LPDWORD lpdwCompression)
{
ASSERT(AfxIsValidAddress(infile,sizeof(CFile),0));

//BITMAPFILEHEADER構造体の読み込み-------------------------------------------------
BITMAPFILEHEADER fh;
UINT uCount=sizeof(BITMAPFILEHEADER);
//ファイルからBITMAPFILEHEADER構造体を読み込みます。
UINT uSize=infile->Read(&fh,uCount);
//ファイルの読み込みに失敗したり、ファイル形式が'BM'でなければ
//FALSEを返して終了します。

if ((uSize<uCount)||(fh.bfType!=0x4D42)) return FALSE;

//BITMAPINFOの読み込み-------------------------------------------------------------
//BITMAPINFO構造体のサイズを算出します。

uCount=fh.bfOffBits-sizeof(BITMAPFILEHEADER);
//算出したサイズがBITMAPINFOHEADER構造体のサイズより小さい場合は、
//FALSEを返して終了します。

if ((int)uCount<sizeof(BITMAPINFOHEADER)) return FALSE;

//BITMAPINFO構造体を格納するメモリーを確保します。
BITMAPINFO* pBmpInfo=(BITMAPINFO*)(new BYTE[uCount]);
uSize=infile->Read(pBmpInfo,uCount);
//ファイル読み込みに失敗したり、
//BITMAPINFOHEADER構造体のbiSizeメンバーの値が正しくない場合は、
//確保したBITMAPINFO構造体用のメモリーを解放した後、FALSEを返して終了します。

if ((uSize<uCount)||
(pBmpInfo->bmiHeader.biSize<sizeof(BITMAPINFOHEADER))||
(pBmpInfo->bmiHeader.biSize>sizeof(BITMAPV5HEADER)))
{
delete[]pBmpInfo;
return FALSE;
}

//DIBの幅の算出
UINT width =pBmpInfo->bmiHeader.biWidth;
//DIBの高さ(絶対値)の算出
UINT height=abs(pBmpInfo->bmiHeader.biHeight);

//ビットマップバイト幅の算出
DWORD widthBytes=WIDTHBYTES(pBmpInfo->bmiHeader.biBitCount*width);
//ピクセルデータのバイト数の算出
DWORD dwSizeImage=widthBytes*height;

//ランレングス圧縮されたDIBの場合は、DIB作成時にエラーにならないように
//BITMAPINFOHEADER構造体のbiCompressionをBI_RGBに戻しておきます。

DWORD dwCompression=pBmpInfo->bmiHeader.biCompression;
if ((dwCompression==BI_RLE4)||(dwCompression==BI_RLE8))
pBmpInfo->bmiHeader.biCompression=BI_RGB;

//読み込んだBITMAPINFO構造体から、DIBセクションを作成します。
LPVOID pvBits=0;
HBITMAP hBitmap=::CreateDIBSection(0,pBmpInfo,DIB_RGB_COLORS,&pvBits,NULL,NULL);

//BITMAPINFO構造体はもういらないのでメモリーを解放します。
delete[]pBmpInfo;
//DIBの作成に失敗したらFALSEを返して終了します。
if (!hBitmap) return FALSE;

//それぞれの圧縮形式に合わせて、イメージピクセルを読み込みます。-------------------
BOOL bResult=FALSE;
switch(dwCompression){
case BI_RGB:
case BI_BITFIELDS:
//圧縮してない場合は、ピクセルデータをそのままコピーします。
uSize=infile->Read(pvBits,dwSizeImage);
if (uSize>=dwSizeImage) bResult=TRUE;
break;
case BI_RLE4:
//4ビットランレングス圧縮の場合は、_DecodeRle4関数を呼び出して解凍します。
bResult=_DecodeRle4(pvBits,dwSizeImage,width,height,infile);
break;
case BI_RLE8:
//8ビットランレングス圧縮の場合は、_DecodeRle8関数を呼び出して解凍します。
bResult=_DecodeRle8(pvBits,dwSizeImage,width,height,infile);
break;
default:
break;
}
//読み込みエラーがある場合は、作成したDIBを削除した後
//FALSEを返して終了します。

if (!bResult){
::DeleteObject(hBitmap);
return FALSE;
}

//第二引数のlpdwCompressionパラメータが有効な場合は、圧縮方法を保存しておきます。
if (AfxIsValidAddress(lpdwCompression,sizeof(DWORD)))
*lpdwCompression=dwCompression;

return hBitmap;
}


hBitmapの内容が、読み込んだDIBファイルから作成したDIBのハンドルになります。

サンプルプログラム(VisualC++net2003ソリューション)DIBFileTest01.zip


上記のzipファイルをダウンロードしてからWinRAR等で解凍し、DIBFileTest01フォルダー内にある「DIBFileTest.sln」を開きます。
「F5」キーを押すと、ビルド確認のダイヤログが表示されるので「Yes」を選択してソリューションをビルドします。



ビルドが終わると直ちにプログラムが自動起動してウィンドウが表示されます。
ウィンドウのメニューで「ファイル」/「開く」を選択して、「ファイルを開く」ダイヤログを表示させます。



resフォルダー内の「mlucc1.bmp」を選択し、「開く」ボタンを押すと、下のような画像が表示されるか確認します。





スポンサーサイト



コメント: 0

この記事へのコメント
ブログ著者にのみ知らせます。

Trackback+Pingback: 0

TrackBack URL for this entry
http://hiroshi0945.blog75.fc2.com/tb.php/1-15dd629c
Listed below are links to weblogs that reference
DIBファイルの読み込み from マルチメディアファイルフォーマット

Home > DIBファイルフォーマット > DIBファイルの読み込み

タグクラウド
ブロとも申請フォーム

この人とブロともになる

ブロとも一覧

このページの先頭へ戻る