PDA

View Full Version : سوال: عکس در opengl



hajizadeh.m
دوشنبه 10 بهمن 1390, 20:33 عصر
سلام دوستان
من خیلی opengl وارد نیستم و نیازی هم ندارم مطالب زیادی رو ازش یاد بگیرم صزفا میخوام با open gl بتونم عکس نمایش میدم.میخواستم ببیتم کسی هست که بتونه راهنمایی کنه که چه کدهایی باید بنویسم و عکس رو توی کدوم پوشه قرار بدم و چه فرمتی داشته باشه عکس.
ممنون

amin1softco
دوشنبه 10 بهمن 1390, 21:08 عصر
برای لود کردن عکس و اینها بستگی به فرمت عکس داره که معمولاً از کتابخانه هایی مثل دویل استفاده می کنند ولی لود کردن عکس هایی مثل bitmap کار سختی نیست در این تاپیک در مورد openGL به صورت خیلی مبتدی بحث کردیم قبلاً
http://barnamenevis.org/showthread.php?209896-%C2%E3%E6%D2%D4-OpenGL

مثال های زیادی هم در این تاپیک قرار خواهیم داد مثل لود کردن مدل های مکس و لود عکس :
http://barnamenevis.org/showthread.php?325504-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%87%D8%A7-%D9%88-%D9%85%D8%AB%D8%A7%D9%84-%D9%87%D8%A7%DB%8C-OpenGL

ضمیمه یک مثال برای لود کردن یک فایل png که با استفاده از کتابخانه gd عکس را لود می کنه....

hajizadeh.m
پنج شنبه 13 بهمن 1390, 18:39 عصر
من این مثال ها رو دیدم اما خیلی پیچیده بودن.
ببینید من یه مثال ساده میخوام با حداقل کد های لازم که یه عکس رو بگیره و نمایش بده.
اگر لطف کنید و کمک کنید ممنون میشم

hajizadeh.m
پنج شنبه 13 بهمن 1390, 18:46 عصر
ببینید دراصل هم پروژه شطرنج هست که میخوام عکس مهره ها و صفحه شطرنج رو بگیره و با توجه به حرکت کاربر اون ها رو در مختصات جدید نمایش بده.
برای همین میخوام به ساده ترین روش ممکن یه مثال داشته باشم که یه عکس رو در یه مختصات نشون بده.
باطم ممنون میشم اگه کمک کنید

amin1softco
پنج شنبه 13 بهمن 1390, 21:14 عصر
دوست من ببنید هر فایل دارای خصوصیات مخصوص به خودشه ولی من برای مثال ساده ترین فایل های تصویری که bitmap باشه رو بررسی کردم شما اول هدر فایل را می خونید و با اطلاعات بدست اومده سراغ دیتا ها ی اون میرید (حالا در مثال قبل ما این کار را با کتابخانه gd کردیم اینجا دستی)و با تابع :
glDrawPixels
تصویر خوتون را در مکان دلخواهتون ترسیم می کنید فایل ضمیمه :
81939

#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glut32.lib")
#include <windows.h>
#include <GL/glut.h>
#include <fstream>
//#include <iostream>
#include <cstdlib>

typedef char byte1;
typedef unsigned char ubyte1;

struct pixmap
{
unsigned width,
height;
ubyte1 *data;

enum {RED = 0, GREEN, BLUE};

pixmap(const char *fname);
pixmap();
~pixmap();

void read(const char *fname);
ubyte1 pixel_elem(int x, int y, int elem);
ubyte1 *pixel_pos(int x, int y);
};


pixmap::pixmap(const char *fname)
: width(0), height(0), data(0)
{
this->read(fname);
}

pixmap::pixmap()
: width(0), height(0), data(0) {}

pixmap::~pixmap()
{
if( data )
delete[] data;
}

void pixmap::read(const char *fname)
{
using namespace std;

unsigned short planes; // number of planes in image (must be 1)
unsigned short bpp; // number of bits per pixel (must be 24)

ifstream fin(fname, ios::in | ios::binary);
if( !fin )
{
//cerr << "File not found " << fname << '\n';
exit(1);
}

fin.seekg(18, ios::cur);

fin.read((byte1 *)&width, sizeof(unsigned));
fin.read((byte1 *)&height, sizeof(unsigned));
//cout << "width: " << width << " height: " << height << '\n';

fin.read((byte1 *)&planes, sizeof(unsigned short));
if( planes != 1 )
{
//cout << "Planes from " << fname << " is not 1: " << planes << "\n";
exit(1);
}

fin.read((byte1 *)&bpp, sizeof(unsigned short));
if( bpp != 24 )
{
//cout << "Bpp from " << fname << " is not 24: " << bpp << "\n";
exit(1);
}

fin.seekg(24, ios::cur);

unsigned size(width * height * 3); // size of the image in bytes (3 is to RGB component).
data = new ubyte1[size];
fin.read((byte1 *)data, size);

ubyte1 R,G,B; // temporary color storage for gbr-rgb conversion.
for( int i(0); i < size; i += 3 )
{
G=data[i];
B=data[i+1];
R=data[i+2];
data[i]=R;
data[i+1]=G;
data[i+2]=B;
}
}

ubyte1 pixmap::pixel_elem(int x, int y, int elem)
{
int pos = (y*width+x) * 3 + elem;
return data[pos];
}

ubyte1 *pixmap::pixel_pos(int x, int y)
{
int pos = (y * width + x) * 3;
return &data[pos];
}


void init(void)
{
glClearColor(1.0,1.0,1.0,0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0,200.0,0.0,150.0);
}

pixmap img;
void lineSegments(void)
{
glClear(GL_COLOR_BUFFER_BIT); //clears display window ??? ???? ???? ?????

glRasterPos2i(0, 0);
glDrawPixels(img.width, img.height, GL_RGB, GL_UNSIGNED_BYTE, img.data);

glFlush(); //process all OGL functions immediately ???? ?? ???? ????
}
void keyboard(unsigned char key, int x, int y)
{
if( key == 27)
exit(0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv); //initialise GLUT
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50, 100); //top left display window pos
glutInitWindowSize(500, 500); //display win width and height in pixel coords
img.read("g:/ff.bmp");
glutCreateWindow(" lines"); //now create display win
init(); //run initilization procs
glutDisplayFunc(lineSegments); //call drawing func
glutKeyboardFunc(keyboard);
glutMainLoop(); //display all and wait
return 0;
}

amin1softco
یک شنبه 16 بهمن 1390, 22:01 عصر
وقتی آدم با کتابخانه ها ایی مثل دویل کار می کنه اصلاً خبر نداره چی می شه ولی الان اگه دقت کرده باشید متوجه میشین که در کد بالا مشکلی وجود نداره ولی عکس درست نمایش داده نمی شه من امروز رفتم تو نخ این ماجرا به یک نکته جالب رسیدم وقتی عکس بیتمپ رو ما می خونیم پیکسل ها به ترتیب GBR ذخیره شدند نه RGB برای همین قطعه کد زیر را به برنامه بالا اضافه کنید مشکل حل می شه :

ubyte1 R,G,B; // temporary color storage
for gbr-rgb conversion. for( int i(0); i < size; i += 3 )
{
G=data[i];
B=data[i+1];
R=data[i+2];
data[i]=R;
data[i+1]=G;
data[i+2]=B;
}
}


یا یک روش جالب تر برای نمایش تصویر دیدم که خیلی سطح پایینتر اومده بود و این کارو کرده بود کد زیر فایل ضمیمه :

http://up7.iranblog.com/images/52218543723565534957.jpg



#include <GL/glut.h>
#include <fstream>
#include <iostream>

unsigned width,height;

void init(void)
{
glClearColor(1.0,1.0,1.0,0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0,(GLdouble)width,0.0,(GLdouble)heigh t);
}

void bitmap(void)
{
using namespace std;
glClear(GL_COLOR_BUFFER_BIT); //clears display window ??? ???? ???? ?????

char pixel;
GLint x, y, xs, xf, ys, i, pix, xpack;
GLfloat pixtmp[3];
ifstream inpaint( "ff.bmp", ios::binary);
inpaint.seekg(54, ios::beg);//begin data bitmap file
xs = 1;
xf = width; //should get x & y from header really
xpack = xf%4; //multiples of 4 bytes/x line
ys = 0;
glBegin(GL_POINTS);
for (y=ys; y<= height; y++) {
for (x = xs; x<= width; x++){
for (i=0; i<=2; i++) { //3 bytes = 1 pixel in 24 bit colour
inpaint.get(pixel);
pix = (unsigned char)pixel;
pixtmp[i] = float(pix)/255.0;
}
glColor3f(pixtmp[2], pixtmp[1], pixtmp[0]); //G B R !
glVertex2i(x,y);
}
if(xpack != 0) for (i=1; i<=xpack; i++) inpaint.get(pixel);;
} //next raster line y
glEnd();

glFlush();
//Sleep(500);
//glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y)
{
if( key == 27)
exit(0);
}
int main(int argc, char** argv)
{
using namespace std;
ifstream inpaint( "ff.bmp", ios::binary);
//w=640
if(!inpaint) {
cout << "File not opened\n";
//exit(1);
}
inpaint.seekg(18, ios::cur);

unsigned short planes; // number of planes in image (must be 1)
unsigned short bpp; // number of bits per pixel (must be 24)

inpaint.read((char *)&width, sizeof(unsigned));
inpaint.read((char *)&height, sizeof(unsigned));

inpaint.read((char *)&planes, sizeof(unsigned short));
if( planes != 1 )
{
//cout << "Planes from " << fname << " is not 1: " << planes << "\n";
exit(1);
}

inpaint.read((char *)&bpp, sizeof(unsigned short));
if( bpp != 24 )
{
//cout << "Bpp from " << fname << " is not 24: " << bpp << "\n";
exit(1);
}
glutInit(&argc, argv); //initialise GLUT
glutInitDisplayMode(GLUT_SINGLE| GLUT_RGB);
glutInitWindowPosition(50, 100); //top left display window pos
glutInitWindowSize(width, height); //display win width and height in pixel coords
glutCreateWindow(" 24-bit bitmap file"); //now create display win
init(); //run initilization procs
glutDisplayFunc(bitmap); //call drawing func
//glutIdleFunc(bitmap);
glutKeyboardFunc(keyboard);
glutMainLoop(); //display all and wait
return 0;
}



اما بازم توصیه می کنم از کتابخانه devil استفاده کنید چون انوع فرمت ها رو ساپورت می کنه و امکان ساخت فایل با اون فرمت رو به شما میده!!! بدون هیچ دردسری