[Solved] Picking pixel colors from Irr Image

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Dareltibus
Posts: 115
Joined: Mon May 17, 2010 7:42 am

[Solved] Picking pixel colors from Irr Image

Post by Dareltibus »

sorry for my english,
i want to load an image and then access each single pixel using the image for example for readin, saving data to image files and so on.
so i have to read data from each color channel of each pixel

Code: Select all

int8 R,G,B,A;

//using an array

R = pixel[1]->red;
G = pixel[3]->green;
B = pixel[111]->blue;
A = pixel[640x479+13]->alpha;


//or a 2dimensional array (3rd dimension is for selectin the color chan)
R = pixel[1][0][0];
G = pixel[3][0][1];
B = pixel[111][0][2];
A = pixel[13][480][3];

or save data to the image array

Code: Select all

pixel[1]->red = R;
etc. irrlicht support this??

if not is possibile fill the array with an extern image library (as DevIL) and then give this array to irrlicht for creating a new texture?

ideal is workin on image as an array for faster computin without any overhead if possibile.

it will be usefull for me because i have another library made from me that save data in images (work using devil)

i tried to find how to do but i failed
Last edited by Dareltibus on Wed May 19, 2010 5:02 pm, edited 1 time in total.
Mag-got
Posts: 42
Joined: Tue Dec 04, 2007 5:53 pm

Post by Mag-got »

Take a look at the IImage class. You create one like this:

Code: Select all

IImage* image = driver->createImage(ECF_COLOR_FORMAT, dimension2d<u32> &size);
In ECF_COLOR_FORMAT put what color format you want, for example ECF_R8G8B8, and in size, the size like

Code: Select all

dimension2d<u32>(512, 512)
You can also create an image from file, using driver->createImageFromFile.

To get and set the pixel data, use image->getPixel(u32 x, u32 y) and image->setPixel(u32 x, u32 y, SColor color)
Dareltibus
Posts: 115
Joined: Mon May 17, 2010 7:42 am

ok thanks

Post by Dareltibus »

ok thanks.. that's my result. I put it here if it will be usefull to anyone.


i assume working with R8G8B8A8 format (As png with alpha channel)

Code: Select all

IImage *dataImage = loadImage(L"pictures/wall.png") //R8G8B8A8
IImage *Image2= loadImage(L"pictures/wall2.png")
u8* pdata= dataImage->lock(); //pointer to image array

int x_dim=(int) dataImage->getDimension().Width
int y_dim=(int) dataImage->getDimension().Height



int x,y; //coords of pixel to pick

x=5;
y=480;

if(  (x<x_dim)&&(y<y_dim)  )
{

//here i replace a pixel in my imagedata with a pixel from another immage
//better having same color format on both image
((u32*)pdata)[y*x_dim + x]=Image2->getPixel(5,480);


//this example don't need the 2 image have the same color format
dataImage->setPixel(5,480,  Image2->getPixel(5,480), false);


u8 R,G,B,A;  //my color channel values

//here extracting colors from that pixel
R= ((u8*)pdata) [  4*y*x_dim  + x];
G= ((u8*)pdata) [  4*y*x_dim  + x + 1 ];
B= pdata [  4*y*x_dim  + x + 2 ]; //of course the same data type 
A= pdata [  4*y*x_dim  + x + 3 ]; //don't need any more cast :)


}
thanks to this i no longer need any support from DevIL library in my game XD. if i find a way to use this data in a faster way i will post it.

Edit: i forget the 4x factor XD

(maybe move to code snippets?)
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Re: ok thanks

Post by Acki »

Dareltibus wrote:if i find a way to use this data in a faster way i will post it.
direct access using lock() and unlock() on the image makes it a lot faster... ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Dareltibus
Posts: 115
Joined: Mon May 17, 2010 7:42 am

ok :)

Post by Dareltibus »

Acki wrote:
Dareltibus wrote:if i find a way to use this data in a faster way i will post it.
direct access using lock() and unlock() on the image makes it a lot faster... ;)
already done ;-)
Dareltibus wrote:

Code: Select all

IImage *dataImage = loadImage(L"pictures/wall.png") //R8G8B8A8
IImage *Image2= loadImage(L"pictures/wall2.png")
u8* pdata= dataImage->lock(); //pointer to image array 
of course these are only silly samples on how to get things work.

here something nicer (i hope:) )


To make the code usefull, a lot more can be done. For example i didn't delete the pdata pointer. I think before Unlocking the image something must be done with it or the whole code will makes only a time waste :)

Ok here i separate the color components of our image into 4 arrays.. why?

well
normally height map is a grey scale image..
a grey color has the same 3 component so (1,1,1) ,(2,2,2),.... = 256 level of grey.

but if we use a R8G8B8A8 image why have only 1 height map with 256 level of height?

we can mix up to 4 different heightmap in only 1 image!(every color channel is a heightmap!) and then we can extract a single heightmap from one of the color channels dividing by 4 (or 3) the space required on the hard disk (for example, big and detailed maps) for storing heightmaps.
(actually irrlicht does not support greyscale image looking only at IImage..h, so maybe this will be usefull for someone)

Code: Select all

IImage *dataImage = loadImage(L"pictures/heightmap1_2_3_4.png") //R8G8B8A8
u8* pdata= dataImage->lock(); //pointer to image array

int x_dim=(int) dataImage->getDimension().Width;
int y_dim=(int) dataImage->getDimension().Height;
int limit = x_dim*y_dim;

u8* redvalues= new u8[limit];
u8* greenvalues= new u8[limit];
u8* bluevalues=new u8[limit];
u8* alphavalues= new u8[limit];

//do something with the image
for(int i=0;i<limit;i++){

        redvalues[i]=pdata[4*i];
        greenvalues[i]=pdata[4*i+1];
        bluevalues[i]=pdata[4*i+2];
        alphavalues[i]=pdata[4*i+3];
}
//now we have the new heightmaps we can release our image data

pdata->unlock();
pdata=0;


//... program runnin


//end of program

device->drop();
delete redvalues;
delete greenvalues;
delete bluevalues;
delete  alphavalues;
	return 0;
Post Reply