「BMP画像を表示する」の編集履歴(バックアップ)一覧はこちら
「BMP画像を表示する」(2015/01/03 (土) 22:13:46) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
<p><strong>BMP画像を表示します。<br />
BMPと言っても今回は24bit画像に限定します。<br />
知っての通り、最もポピュラーで広く使われている画像形式ですが<br />
BMP形式は種類が複数存在し、データサイズも大きいので<br />
最近では、あまり使われなくなってきました。</strong></p>
<p> <img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&act=open&pageid=67&file=bmpload.png" /></p>
<table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td>
<p>#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br />
#include <GL/freeglut/freeglut.h><br />
#include <stdio.h></p>
<p>#define WIDTH 320<br />
#define HEIGHT 240</p>
<p>class BMP<br />
{<br />
public:<br />
unsigned long sizeX; //横<br />
unsigned long sizeY; //縦<br />
char *Data; //画像データ格納<br />
bool Load(char *filename);<br />
GLuint texture;<br />
void TexSet();<br />
BMP(char *FileName);<br />
};</p>
<p>BMP::BMP(char *FileName){<br />
Load(FileName);<br />
TexSet();<br />
}<br />
bool BMP::Load(char *FileName) {<br />
FILE *File;<br />
unsigned long size;// イメージのバイトサイズ<br />
unsigned long i;// カウンタ<br />
unsigned short int planes; //デバイス面数<br />
unsigned short int bpp; // ピクセル数<br />
char temp; // カラー関係作業用<br />
//ファイルオープン<br />
if ((File = fopen(FileName, "rb"))==NULL){<br />
printf("ファイルがありません");<br />
return false;<br />
}<br />
//ビットマップの幅データ部分へ移動<br />
fseek(File, 18, SEEK_CUR);<br />
//横幅を読み込む<br />
if ((i = fread(&sizeX, 4, 1, File)) != 1) {<br />
printf("読み込みエラー");<br />
return false;<br />
}<br />
//縦幅を読み込む<br />
if ((i = fread(&sizeY, 4, 1, File)) != 1) {<br />
printf("読み込みエラー");<br />
return false;<br />
}<br />
//画像サイズの計算<br />
size = sizeX * sizeY * 3;//プレーン数を読み込む<br />
if ((fread(&planes, 2, 1, File)) != 1) { //bmpは「1」になる<br />
printf("プレーン数が読み込めません");<br />
return false;<br />
}<br />
if (planes != 1) {<br />
printf("プレーン数が1以外です");<br />
return false;<br />
}<br />
//ピクセル値を読み込む<br />
if ((i = fread(&bpp, 2, 1, File)) != 1) {<br />
printf("ビット数が読めません");<br />
return false;<br />
}<br />
if (bpp != 24) {//24bppでなければエラー<br />
printf("24ビット画像ではありません");<br />
return false;<br />
}<br />
//24ビット飛ばして、カラーデータ(RGB)部分へ<br />
fseek(File, 24, SEEK_CUR); //データ読み込み<br />
Data = (char *) malloc(size);<br />
if (Data == NULL) {<br />
printf("メモリが確保できません");<br />
return false;<br />
}<br />
if ((i = fread(Data, size, 1, File)) != 1) {<br />
printf("データが読めません");<br />
return false;<br />
}<br />
for (i=0;i<size;i+=3) { //bgr -> rgb<br />
temp = Data[i];<br />
Data[i] = Data[i+2];<br />
Data[i+2] = temp;<br />
}<br />
return true;<br />
}</p>
<p>void BMP::TexSet()<br />
{<br />
glEnable( GL_TEXTURE_2D );<br />
glGenTextures( 1, &texture );<br />
glBindTexture( GL_TEXTURE_2D, texture );<br />
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );<br />
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );<br />
glTexImage2D( GL_TEXTURE_2D, 0, 3, sizeX, sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
Data );<br />
glBindTexture( GL_TEXTURE_2D, 0 );<br />
}</p>
<p>BMP *bmp;</p>
<p>void display(void)<br />
{<br />
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />
glMatrixMode(GL_MODELVIEW);<br />
glLoadIdentity();<br />
glOrtho(0.0, WIDTH, HEIGHT, 0.0, -1.0, 1.0);</p>
<p> glEnable(GL_TEXTURE_2D);//テクスチャ有効<br />
glBindTexture( GL_TEXTURE_2D, bmp->texture );<br />
glEnable(GL_ALPHA_TEST);//アルファテスト開始<br />
glBegin(GL_POLYGON);<br />
glTexCoord2f(0.0f, 0.0f); glVertex2d(10 , 230);//左下<br />
glTexCoord2f(0.0f, 1.0f); glVertex2d(10 , 10);//左上<br />
glTexCoord2f(1.0f, 1.0f); glVertex2d( 310 , 10);//右上<br />
glTexCoord2f(1.0f, 0.0f); glVertex2d( 310 , 230);//右下<br />
glEnd();<br />
glDisable(GL_ALPHA_TEST);//アルファテスト終了<br />
glDisable(GL_TEXTURE_2D);//テクスチャ無効</p>
<p> glutSwapBuffers();<br />
}<br />
void idle(void)<br />
{<br />
glutPostRedisplay();<br />
}<br />
void Init(){<br />
glClearColor(0.0, 0.0, 0.0, 1.0);<br />
glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);<br />
bmp = new BMP("test.bmp");<br />
}</p>
<p>int main(int argc, char *argv[])<br />
{<br />
glutInitWindowPosition(100, 100);<br />
glutInitWindowSize(WIDTH, HEIGHT);<br />
glutInit(&argc, argv);<br />
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />
glutCreateWindow("BMP画像を読み込んで表示");<br />
glutDisplayFunc(display);<br />
glutIdleFunc(idle);<br />
Init();<br />
glutMainLoop();<br />
return 0;<br />
}</p>
</td>
</tr></tbody></table><p> </p>
<p><strong>BMP画像を表示します。<br />
BMPと言っても今回は24bit画像に限定します。<br />
知っての通り、最もポピュラーで広く使われている画像形式ですが<br />
BMP形式は種類が複数存在し、データサイズも大きいので<br />
最近では、あまり使われなくなってきました。</strong></p>
<p> <img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=67&file=bmp.png" /></p>
<table border="1" cellpadding="1" cellspacing="1" style="width:100px;"><tbody><tr><td>ファイル</td>
</tr><tr><td><a href="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=67&file=main.cpp">
main.cpp</a></td>
</tr><tr><td>
<p><a href="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=67&file=sample.bmp">
sample.bmp</a></p>
<p><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=67&file=sample.bmp" /></p>
</td>
</tr></tbody></table><p>main.cpp</p>
<table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td>
<p>#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br />
#include <GL/freeglut/freeglut.h><br />
#include <stdio.h></p>
<p>#define WIDTH 320<br />
#define HEIGHT 240</p>
<p>class BMP<br />
{<br />
public:<br />
unsigned long sizeX; //横<br />
unsigned long sizeY; //縦<br />
char *Data; //画像データ格納<br />
bool Load(char *filename);<br />
GLuint texture;<br />
void TexSet();<br />
BMP(char *FileName);<br />
};</p>
<p>BMP::BMP(char *FileName){<br />
Load(FileName);<br />
TexSet();<br />
}<br />
bool BMP::Load(char *FileName) {<br />
FILE *File;<br />
unsigned long size;// イメージのバイトサイズ<br />
unsigned long i;// カウンタ<br />
unsigned short int planes; //デバイス面数<br />
unsigned short int bpp; // ピクセル数<br />
char temp; // カラー関係作業用<br />
//ファイルオープン<br />
if ((File = fopen(FileName, "rb"))==NULL){<br />
printf("ファイルがありません");<br />
return false;<br />
}<br />
//ビットマップの幅データ部分へ移動<br />
fseek(File, 18, SEEK_CUR);<br />
//横幅を読み込む<br />
if ((i = fread(&sizeX, 4, 1, File)) != 1) {<br />
printf("読み込みエラー");<br />
return false;<br />
}<br />
//縦幅を読み込む<br />
if ((i = fread(&sizeY, 4, 1, File)) != 1) {<br />
printf("読み込みエラー");<br />
return false;<br />
}<br />
//画像サイズの計算<br />
size = sizeX * sizeY * 3;//プレーン数を読み込む<br />
if ((fread(&planes, 2, 1, File)) != 1) { //bmpは「1」になる<br />
printf("プレーン数が読み込めません");<br />
return false;<br />
}<br />
if (planes != 1) {<br />
printf("プレーン数が1以外です");<br />
return false;<br />
}<br />
//ピクセル値を読み込む<br />
if ((i = fread(&bpp, 2, 1, File)) != 1) {<br />
printf("ビット数が読めません");<br />
return false;<br />
}<br />
if (bpp != 24) {//24bppでなければエラー<br />
printf("24ビット画像ではありません");<br />
return false;<br />
}<br />
//24ビット飛ばして、カラーデータ(RGB)部分へ<br />
fseek(File, 24, SEEK_CUR); //データ読み込み<br />
Data = (char *) malloc(size);<br />
if (Data == NULL) {<br />
printf("メモリが確保できません");<br />
return false;<br />
}<br />
if ((i = fread(Data, size, 1, File)) != 1) {<br />
printf("データが読めません");<br />
return false;<br />
}<br />
for (i=0;i<size;i+=3) { //bgr -> rgb<br />
temp = Data[i];<br />
Data[i] = Data[i+2];<br />
Data[i+2] = temp;<br />
}<br />
return true;<br />
}</p>
<p>void BMP::TexSet()<br />
{<br />
glEnable( GL_TEXTURE_2D );<br />
glGenTextures( 1, &texture );<br />
glBindTexture( GL_TEXTURE_2D, texture );<br />
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );<br />
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );<br />
glTexImage2D( GL_TEXTURE_2D, 0, 3, sizeX, sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
Data );<br />
glBindTexture( GL_TEXTURE_2D, 0 );<br />
}</p>
<p>BMP *bmp;</p>
<p>void display(void)<br />
{<br />
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />
glMatrixMode(GL_MODELVIEW);<br />
glLoadIdentity();<br />
glOrtho(0.0, WIDTH, HEIGHT, 0.0, -1.0, 1.0);</p>
<p> glEnable(GL_TEXTURE_2D);//テクスチャ有効<br />
glBindTexture( GL_TEXTURE_2D, bmp->texture );<br />
glEnable(GL_ALPHA_TEST);//アルファテスト開始<br />
glBegin(GL_POLYGON);<br />
glTexCoord2f(0.0f, 0.0f); glVertex2d(10 , 230);//左下<br />
glTexCoord2f(0.0f, 1.0f); glVertex2d(10 , 10);//左上<br />
glTexCoord2f(1.0f, 1.0f); glVertex2d( 310 , 10);//右上<br />
glTexCoord2f(1.0f, 0.0f); glVertex2d( 310 , 230);//右下<br />
glEnd();<br />
glDisable(GL_ALPHA_TEST);//アルファテスト終了<br />
glDisable(GL_TEXTURE_2D);//テクスチャ無効</p>
<p> glutSwapBuffers();<br />
}<br />
void idle(void)<br />
{<br />
glutPostRedisplay();<br />
}<br />
void Init(){<br />
glClearColor(0.0, 0.0, 0.0, 1.0);<br />
glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);<br />
bmp = new BMP("sample.bmp");<br />
}</p>
<p>int main(int argc, char *argv[])<br />
{<br />
glutInitWindowPosition(100, 100);<br />
glutInitWindowSize(WIDTH, HEIGHT);<br />
glutInit(&argc, argv);<br />
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />
glutCreateWindow("BMP画像を読み込んで表示");<br />
glutDisplayFunc(display);<br />
glutIdleFunc(idle);<br />
Init();<br />
glutMainLoop();<br />
return 0;<br />
}</p>
</td>
</tr></tbody></table><p> </p>