读书人

OpenGL 取示 灰BMP,该如何处理

发布时间: 2012-02-09 18:22:27 作者: rapoo

OpenGL 取示 灰BMP
大家好, 小弟是初OpenGL的新手, 有些教,

我目前在 "取示灰影像",

看到programmer-club的白老鼠大大也分享了的code(彩色影像),

那我想由於彩色bmp是24bit, 灰是8bit, 把彩色*3, 改灰*1,

就把程式改了一下, 如下所示:

/////////////////////////
// g_bmp.h
//
// Created by Gary Ho, ma_hty@hotmail.com, 2005
//

#ifndef G_BMP_H
#define G_BMP_H

class GBmp
{
public:
int w,h;
unsigned char *rgb;

GBmp();
~GBmp();

void load( const char *spath );
void load( int width, int height )

/////////////////////////
// glutTest01.cpp
// Created by Gary Ho, ma_hty@hotmail.com, 2005
//

#include

#include "GL/glut.h"
#include "g_bmp.h"

GBmp bm0;

void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glRasterPos2f( -bm0.w/512.0, -bm0.h/512.0 );
glDrawPixels( bm0.w, bm0.h, GL_LUMINANCE, GL_UNSIGNED_BYTE, bm0.rgb );
glutSwapBuffers();
}

void OnKey(unsigned char key, int x, int y)
{
switch(key)
{
case 27:
exit(0);
break;
}
}

int main( int argc, char** argv )
{
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA );
glutInitWindowSize( 512, 512 );
glutInitWindowPosition (100, 100);
glutCreateWindow( "hihi" );

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glutKeyboardFunc(OnKey);
glutDisplayFunc(display);

bm0.load( "aa.bmp" );
glutMainLoop();
}

/////////////////////////
// g_bmp.cpp
//
// Created by Gary Ho, ma_hty@hotmail.com, 2005
//
/////////////////////////
// g_bmp.cpp
//
// Created by Gary Ho, ma_hty@hotmail.com, 2005
//

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#include "g_bmp.h"

#pragma pack( push, 1 )
typedef struct _bmp_header_info
{
unsigned short bfType;
unsigned int bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned int bfOffBits;

// bitmap header
unsigned int biSize;
int biWidth;
int biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
int biXpelsPerMeter;
int biYpelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} bmp_header_info;
#pragma pack( pop )

GBmp::GBmp()
{
memset( this, 0, sizeof(GBmp) );
}

GBmp::~GBmp()
{
if(rgb!=NULL)
free(rgb);
}

void GBmp::load( const char *spath )
{

bmp_header_info bhi;
{
FILE *f0 = fopen( spath, "rb" );
if( f0==NULL )
{
printf( "[Error] GBmp::load, file %s not found.\n", spath );
exit(-1);
}

fread( &bhi, sizeof(bmp_header_info), 1, f0 );
fclose(f0);
}

if( bhi.bfType != 'MB' )
{
printf( "[Error] GBmp::load, not bitmap file\n" );
exit(-1);
}

if( bhi.biCompression != 0 )
{
printf( "[Error] GBmp::load, only uncompressed bitmap is supported\n" );
exit(-1);
}

//if( bhi.biBitCount != 24 )
if( bhi.biBitCount != 8 )
{
printf( "[Error] GBmp::load, must be RGB888 bitmap\n" );
exit(-1);
}

if(rgb) free(rgb);

w = bhi.biWidth;


h = bhi.biHeight;
//rgb = (unsigned char*) malloc( w*h*3*sizeof(unsigned char) );
rgb = (unsigned char*) malloc( w*h*1*sizeof(unsigned char) );
{
FILE *f0 = fopen( spath, "rb" );
fseek( f0, bhi.bfOffBits, SEEK_SET );
int j;
for( j=0; j<h; j++ )
{
fread( &rgb[j*w*1], sizeof(unsigned char), w*1, f0 );
fseek( f0, (4-w*1%4)%4, SEEK_CUR );
}
fclose(f0);
}
rb_swap();
}

void GBmp::load( int width, int height )
{
if(rgb) free(rgb);

w = width;
h = height;
rgb = (unsigned char*) malloc( w*h*1*sizeof(unsigned char) );
memset( rgb, 0, w*h*1*sizeof(unsigned char) );
}

void GBmp::load( int width, int height, unsigned char *rgb_data )
{
if(rgb) free(rgb);

w = width;
h = height;
rgb = (unsigned char*) malloc( w*h*1*sizeof(unsigned char) );
memcpy( rgb, rgb_data, w*h*1*sizeof(unsigned char) );
}

void GBmp::flip_vectical()
{
unsigned char* tmp_rgb = (unsigned char*) malloc( w*h*1*sizeof(unsigned char) );
int j;
for( j=0; j<h; j++ )
memcpy( &tmp_rgb[j*w*1], &rgb[(h-j-1)*w*1], w*1*sizeof(unsigned char) );
memcpy( rgb, tmp_rgb, w*h*1*sizeof(unsigned char) );
free(tmp_rgb);
}

void GBmp::rb_swap()
{
unsigned char tmp;
int i,j;
for( j=0; j<h; j++ )
for( i=0; i<w; i++ )
{
tmp = rgb[(j*w+i)*1];
rgb[(j*w+i)*1] = rgb[(j*w+i)*1+2];
rgb[(j*w+i)*1+2] = tmp;
}
}

void GBmp::save( const char *spath )
{
bmp_header_info bhi;
bhi.bfType = 'MB';
bhi.bfSize = w*h*1*sizeof(unsigned char) + sizeof(bhi);
bhi.bfReserved1 = 0;
bhi.bfReserved2 = 0;
bhi.bfOffBits = sizeof(bhi);

bhi.biSize = 40;
bhi.biWidth = w;
bhi.biHeight = h;
bhi.biPlanes = 1;
bhi.biBitCount = 8;
bhi.biCompression = 0;
bhi.biSizeImage = 0;
bhi.biXpelsPerMeter = 0;
bhi.biYpelsPerMeter = 0;
bhi.biClrUsed = 0;
bhi.biClrImportant = 0;

int j;
GBmp a;
a.load( w,h, rgb );
unsigned char pad[1] = {0};

FILE *f0 = fopen( spath, "wb" );
fwrite( &bhi, sizeof(bmp_header_info), 1, f0 );
for( j=0; j<h; j++ )
{
fwrite( &a.rgb[j*w*1], sizeof(unsigned char), w*1, f0 );
}
fclose(f0);
}

支程式有三案
g_bmp.cpp
glutTest01.cpp
g_bmp.h

[解决办法]
我是这样处理灰度图像的,将读入内存的灰度图像转换为RGB图像(其中三通道的值相等R=G=B),再使用openGL显示。不知道有没有其他方法

读书人网 >VC/MFC

热点推荐