PDA

View Full Version : Need some suggestion about reading and displaying an image file



jenny_wui
04-26-2013, 08:38 AM
Hello, I would like to read a jpeg file and display the pixel using glColor3f. I have extracted the pixel dimension from the image.
Now my quetion is pixelWidth by pixelHeight are the number of bytes. I should deduct that number from the whole amount of bytes and then should I just start reading the bytes (unsigned char) and try to display it?
Please provide me some suggestion.
Thanks in advance.

carsten neumann
04-26-2013, 09:42 AM
Now my quetion is pixelWidth by pixelHeight are the number of bytes.


That would only be true for an image with a single channel and no compression. More common would be 3-4 channels (RGB, RGBA) and compression, hence use libjpeg (http://libjpeg.sourceforge.net/) to read the image from disk, or use a multi image format loader library, e.g. OpenImageIO (http://sites.google.com/site/openimageio), DevIL (http://openil.sourceforge.net/).

The Little Body
04-26-2013, 10:36 AM
DevIL is a good image loader library

jenny_wui
04-26-2013, 11:43 AM
As i need to manipulate the pixel value and I have already started coding in C, I just need the information from where the image data starts i.e. what is the marker for that as I already have the width and height of the image. It would be good if you provide some suggestions regarding this.

skeezix6
04-26-2013, 01:04 PM
These libs will give you access to uncompressed pixels if you need to modify the image. You really don't want to write your own jpeg decoder...

The Little Body
04-26-2013, 02:56 PM
You can too use libTIFF http://www.libtiff.org/ , libTGA http://tgalib.sourceforge.net/ or libJPEG http://libjpeg.sourceforge.net/ but DevIL is very more generic and work really very well for loading various images files formats into OpenGL textures such as listed at http://openil.sourceforge.net/features.php

Generally, an image file format is a very more complex thing that only a marker where begin a single succession of height lines of width columns of 8 bits gray pixels ...
(pixels can be stored on 1/2/4/8 bits on B/W, RGB, RGBA, GRAY or PALETTE INDICES, on form of lines, planes, strips, tiles and patchs .. and all this with a lot of various compression schemes)
=> take a look at http://en.wikipedia.org/wiki/Image_file_formats for to have an idea of the number of differences that you can find between two images files formats ...

jenny_wui
04-26-2013, 03:16 PM
I tried to look at libjpeg website, but didn't find any particular direction/ example about the use of it. Please provide me some suggestions.

Carmine
04-26-2013, 03:29 PM
I tried to look at libjpeg website, but didn't find any particular direction/ example about the use of it. Please provide me some suggestions.I have also found DevIL to be fairly easy to use. They give you examples. Like you, I am inputting images, combining them according to some complex rules, and displaying the result on the screen. So I need access to the RGB values of every pixel.

The Little Body
04-26-2013, 03:34 PM
You can find DevIL tutorials at http://openil.sourceforge.net/tuts/tut_step/index.htm, http://openil.sourceforge.net/tuts/tut_5/index.htm or http://content.gpwiki.org/index.php/DevIL:Tutorials:Basics

Or only google "devil opengl tutorial" for to find a lot more DevIL's tutorials
(I find the link http://content.gpwiki.org/index.php/DevIL:Tutorials:Basics very didactic, you can easily replace the SDL part by the GLUT equivalent for example)

Here a very simple example using DevIL and GLUT :
(it's only a fast port from SDL to GLUT of the last link)


#include <IL/il.h>
#include <GL/glut.h>

int width = 640;
int height = 480;


/* Initialize OpenGL Graphics */
void initGL()
{
glViewport(0, 0, width, height);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, width, height, 0.0, 0.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
/* Handler for window-repaint event. Called back when the window first appears and
whenever the window needs to be re-painted. */
void display()
{
// Clear color and depth buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); // Operate on model-view matrix

/* Draw a quad */
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(0, 0);
glTexCoord2i(0, 1); glVertex2i(0, height);
glTexCoord2i(1, 1); glVertex2i(width, height);
glTexCoord2i(1, 0); glVertex2i(width, 0);
glEnd();

glutSwapBuffers();
}

/* Handler for window re-size event. Called back when the window first appears and
whenever the window is re-sized with its new width and height */
void reshape(GLsizei newwidth, GLsizei newheight)
{
// Set the viewport to cover the new window
glViewport(0, 0, width=newwidth, height=newheight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, width, height, 0.0, 0.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}

/* Load an image using DevIL and return the devIL handle (-1 if failure) */
int LoadImage(char *filename)
{
ILboolean success;
ILuint image;

ilGenImages(1, &image); /* Generation of one image name */
ilBindImage(image); /* Binding of image name */
success = ilLoadImage(filename); /* Loading of the image filename by DevIL */

if (success) /* If no error occured: */
{
/* Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA */
success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);

if (!success)
{
return -1;
}
}
else
return -1;

return image;
}


int main(int argc, char **argv)
{

GLuint texid;
int image;

if ( argc < 1)
{
/* no image file to display */
return -1;
}

if (ilGetInteger(IL_VERSION_NUM) < IL_VERSION)
{
printf("wrong DevIL version \n");
return -1;
}

/* Initialization of DevIL */
ilInit();

/* load the file picture with DevIL */
image = LoadImage(argv[1]);
if ( image == -1 )
{
printf("Can't load picture file %s by DevIL \n", argv[1]);
return -1;
}

/* GLUT init */
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode
glutInitWindowSize(640, 480); // Set the window's initial width & height
glutCreateWindow(argv[0]); // Create window with the name of the executable
glutDisplayFunc(display); // Register callback handler for window re-paint event
glutReshapeFunc(reshape); // Register callback handler for window re-size event


/* OpenGL texture generation */
glGenTextures(1, &texid); /* Texture name generation */
glBindTexture(GL_TEXTURE_2D, texid); /* Binding of texture name */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* We will use linear interpolation for magnification filter */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); /* We will use linear interpolation for minifying filter */
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT),
0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData()); /* Texture specification */

/* Main loop */
initGL();
glutMainLoop();

/* Delete used resources and quit */
ilDeleteImages(1, &image); /* Because we have already copied image data into texture data we can release memory used by image. */
glDeleteTextures(1, &texid);

return 0;
}


This compile like this on a linux box :


gcc devil_example.c -lGL -lglut -lIL -o devil_example


Note that with the line "success = ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);" from the original SDL code, the file image isn't good loaded on my Linux box (the texture is gray + shifted)
=> I have to use "success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);" instead
(I think this is because the default pixel color format is RGB24 on SDL when it's RGBA on GLUT)

jenny_wui
04-28-2013, 01:42 PM
Thank you very much Little body, I have installed devil and tried your code. It works fine in loading a jpeg image. Now Could you help a bit more. How to manipulate the pixel values of my image and then write it back as a new jpg file. Thanks in advance.

The Little Body
04-28-2013, 05:37 PM
For to manipulate the image, alls informations you need are already used at the line that load the texture from the RAM to OpenGL ...



glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData()); /* Texture specification */


For to write it, use this DevIL functions :


ILboolean ilSaveImage(const char *FileName);

(you can found a .pdf file that explain how to use DevIL at http://openil.sourceforge.net/docs/DevIL%20Manual.pdf)

jenny_wui
04-30-2013, 08:23 AM
Thanks a lot.