首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

OpenGL 讀取與顯示 灰階BMP,该如何处理

2012-02-09 
OpenGL 讀取與顯示 灰階BMP大家好, 小弟是初學OpenGL的新手, 有些問題寫請教,我目前在測試 讀取與顯示灰

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显示。不知道有没有其他方法

热点排行