【发布时间】:2015-04-24 09:25:41
【问题描述】:
我正在开发一个读取 PPM 文件(P6 格式)并用 Opengl 和 c++ 显示它的程序。
我的代码可以显示 PPM 图像,但是图像的颜色不正确。人的脸应该是棕色的,背景应该是蓝色的。
我使用 ifstream 读取文件并将数据放入 char 数组 dataByte[] 中。然后我使用 glDrawPixels() 来显示图像。它适用于 PGM 文件。
这是我的代码。我需要对图像进行一些操作。操作工作正常,但仅当我显示 PPM 文件时,图像的颜色与在 Photoshop 中显示的颜色不同。
背景应该是蓝色的,但它变成了红色等等...我现在无法上传图片,所以这里是图片截图的链接
the image should be display but it display in this way
我认为问题出在我读取数据的函数上。
#include "stdafx.h"
#include <stdlib.h>
#include <GL/glut.h>
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
using namespace std;
GLint width;
GLint height;
GLint wholeLength;
GLint grayLevel;
//GLubyte *dataByte;
char* dataByte;
GLint type;
//ignore the comment in PPM
void ignoreComment(ifstream &f){
char buf[1024];
char t;
t=f.peek();
while (t=='\n' || t=='\r'){
f.get();
t=f.peek();
}
if(t=='#'){
f.getline(buf,1023);
}
}
这是我读取图像并将数据放入 dataByte[] 的函数。我认为问题在于我从 PPM 文件中获取数据的方式。但我不知道如何解决它
void readImage(string fname){
ifstream f;
f.open(fname.c_str(), ifstream::in | ifstream::binary);
cout<<fname.c_str()<<endl;
if(!f.is_open() ){
cout<<"Cannot open the file"<<endl;
return;
}
else
cout<<"opened"<<endl;
//get type
ignoreComment(f);
string temp;
f >> temp;
if( (!(temp[0]=='P' ) && !(temp[0]=='p' ) )||
( !(temp[1]=='6' ) && !(temp[1]=='5' ))
){
cout<<temp<<endl;
cout<<"cannot read this format"<<endl;
f.close();
return;
}
else{
cout<<"file opened"<<endl;
cout<<temp<<endl;
}
if(temp[1]=='5'){
type=5;
cout<<"type:"<<type<<endl;
}
if(temp[1]=='6'){
type=6;
cout<<"type:"<<type<<endl;
}
//get width,height
ignoreComment(f);
f >> width;
ignoreComment(f);
f >> height;
ignoreComment(f);
f >> grayLevel;
if(width < 1 || height < 1 || grayLevel < 0 || grayLevel >255){
cout<<"Cannot get the size or gray level"<<endl;
f.close();
return;
}
//allocate data size
if( type==5){
wholeLength=width*height;
cout<<"width="<<width<<" height:"<<height<<endl;
}
if(type==6){
wholeLength=3*width*height;
cout<<"width="<<width<<" height:"<<height<<endl;
}
if(type==5 || type ==6){
//dataByte=new GLubyte[wholeLength];
dataByte=new unsigned char[wholeLength];
//f.read((char*)&dataByte[0], wholeLength);
//GLubyte j;
int w;
if(type==5)
w=width;
if(type==6)
w=3*width;
int count=0;int counth=0;
for(int i=height;i>0;i--){
for(int k=0;k<w;k++){
//j=(GLubyte)f.get();
//dataByte[(i-1)*w+k]=j;
f.read((char*)&dataByte[(i-1)*w+k],sizeof(unsigned char));
count++;
}
cout<<"count:"<<count<<endl;
count=0;
counth++;
}
cout<<"counth:"<<counth<<endl;
}
f.close();
}
int main(int argc, char *argv[] ) {
//string n;
//cout<<"Please enter the name of the image"<<endl;
//cin>>n;
readImage("small.ppm");
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
ori();
getChoice();
glutMainLoop();
return 0;
}
这是我的显示功能。它们可以显示 PGM 文件和 PPM 文件。
void drawAsType(char * d){
if(type==5){
glDrawPixels(width,height,GL_LUMINANCE,GL_UNSIGNED_BYTE,d);
glFlush();
glutSwapBuffers();
}
if(type==6 ){
glDrawPixels(width,height,GL_RGB,GL_UNSIGNED_BYTE,d);
glFlush();
glutSwapBuffers();
}
}
void changeSize(int w,int h){
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLfloat)w,0.0,(GLfloat)h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void display(void){
glClear(GL_COLOR_BUFFER_BIT);
glRasterPos2i(0,0);
glColor3f(1.0f,1.0f,1.0f);
drawAsType(dataByte);
}
void ori(){
glutInitWindowSize(width,height);
glutCreateWindow("Origin");
glutReshapeFunc(changeSize);
glutDisplayFunc(&display);
}
谁能帮帮我?
【问题讨论】:
-
查看图像,您似乎在读取或传递给 OGL 的某处有一个错误。橙色 RGB(251, 111, 41) 变成 RGB(31, 251, 111),蓝色 RGB(28, 63, 167) 变成 RGB(160, 28, 63)。看到图案了吗? :-)
-
谢谢@haraldK,正如你所说,我发现我的程序出了什么问题。我确实忽略了图像数据块中的第一个字符。