Reading Images

A

Alexandro Kez

Hei there, ruby coders,
I'm quite new to ruby and have just done some very basic projects for my
university and now have encountered a problem while programming CG with
openGL bindings for ruby. Most my mates are very pesimistic about
programming CG with ruby, but not me.
Well, my actual problem is:
I'm trying to put a texture on some shape, thus I need to load a JPEG
to ram, get it's width/height and read every number that represents
color code of each pixel. I just need to get width/height + array of
numbers that would represent colors. With ruby I can read only lines as
string from file? Or I'm not right?
 
R

Robert Klemme

2009/12/7 Alexandro Kez said:
Hei there, ruby coders,
I'm quite new to ruby and have just done some very basic projects for my
university and now have encountered a problem while programming CG with
openGL bindings for ruby. Most my mates are very pesimistic about
programming CG with ruby, but not me.
Well, my actual problem is:
=A0I'm trying to put a texture on some shape, thus I need to load a JPEG
to ram, get it's width/height and read every number that represents
color code of each pixel. I just need to get width/height + array of
numbers that would represent colors. With ruby I can read only lines as
string from file? Or I'm not right?

You can read arbitrary binary content:

data =3D File.open("foo.jpg", "rb") {|io| io.read}

Does that help?

Kind regards

robert
 
A

Alexandro Kez

Ok, here's the code. I'm just trying to load it and put on a quad. 500
and 500 are the original width and height of pic.

name = GL.GenTextures(1);

data = File.open("grass.jpg", "rb") {|io| io.read}

GL.PixelStorei(GL::UNPACK_ALIGNMENT, 1);

GL.BindTexture(GL::TEXTURE_2D, name[0]);

GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_S, GL::CLAMP);
GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_T, GL::CLAMP);
GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_MAG_FILTER,GL::NEAREST);
GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_MIN_FILTER,GL::NEAREST);
GL.TexImage2D(GL::TEXTURE_2D, 0, GL::RGBA, 500,
500, 0, GL::RGBA, GL::UNSIGNED_BYTE,
data.unpack("C*"));


GL.BindTexture(GL::TEXTURE_2D,name[0]);
GL.Begin(GL::QUADS);
GL.TexCoord(0.0, 0.0); GL.Vertex(-20.0, 0.0, -20.0);
GL.TexCoord(0.0, 1.0); GL.Vertex(-20.0, 0.0, 20.0 );
GL.TexCoord(1.0, 1.0); GL.Vertex(20.0, 0.0, 20.0 );
GL.TexCoord(1.0, 0.0); GL.Vertex(20.0, 0.0, -20.0 );
GL.End();



The error I get:
Length of specified data doesn't correspond to format and type
parameters passed. Calculated length: 1000000 (ArgumentError)

As I think it may be due to the fact it contains more data, like width
and height in itself and the datatypes, just don't get it. By the way,
if I read it, it's still a string, why? Why do I have to pack/unpack?
thanks to every respond
 
R

Robert Klemme

2009/12/7 Alexandro Kez said:
Ok, here's the code. I'm just trying to load it and put on a quad. 500
and 500 are the original width and height of pic.

=A0 name =3D GL.GenTextures(1);

=A0 data =3D File.open("grass.jpg", "rb") {|io| io.read}

=A0 GL.PixelStorei(GL::UNPACK_ALIGNMENT, 1);

=A0 GL.BindTexture(GL::TEXTURE_2D, name[0]);

=A0 GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_S, GL::CLAMP);
=A0 GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_T, GL::CLAMP);
=A0 GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_MAG_FILTER,GL::NEAREST);
=A0 GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_MIN_FILTER,GL::NEAREST);
=A0 GL.TexImage2D(GL::TEXTURE_2D, 0, GL::RGBA, 500,
=A0 =A0500, 0, GL::RGBA, GL::UNSIGNED_BYTE,
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0data.unpack("C*"));


=A0 =A0GL.BindTexture(GL::TEXTURE_2D,name[0]);
=A0 =A0GL.Begin(GL::QUADS);
=A0 =A0GL.TexCoord(0.0, 0.0); GL.Vertex(-20.0, 0.0, -20.0);
=A0 =A0GL.TexCoord(0.0, 1.0); GL.Vertex(-20.0, 0.0, 20.0 );
=A0 =A0GL.TexCoord(1.0, 1.0); GL.Vertex(20.0, 0.0, 20.0 );
=A0 =A0GL.TexCoord(1.0, 0.0); GL.Vertex(20.0, 0.0, -20.0 );
=A0 =A0GL.End();



The error I get:
Length of specified data doesn't correspond to format and type
parameters passed. Calculated length: 1000000 (ArgumentError)

As I think it may be due to the fact it contains more data, like width
and height in itself and the datatypes, just don't get it. By the way,
if I read it, it's still a string, why? Why do I have to pack/unpack?
thanks to every respond

Do you have to unpack? I don't know the GL API but I doubt it would
require to unpack the String. Did you test what happens when you
unpack? You get an Array full of ints. That does not look like a
type that a low level graphics rendering library would use. Methinks
GL would rather use a String (as the Ruby type for binary data). What
do the docs say?

Kind regards

robert


--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
R

Rob Biedenharn

A jpeg is more complicated that that. (All image formats are actually.)

Here's http://gist.github.com/89738 some code that can find the width
and height of an image in PNG, GIF, or JPEG format. Notice how much
more complicated the JPEG code is because you have to find the right
JFIF segment and there can be embedded thumbnails and such so a simple
regexp search for the first part that looks like the size won't work.

You might want to look at ImageMagick (RMagick is the ruby interface)
or some other image library that will find the pixel data for you.

-Rob

Ok, here's the code. I'm just trying to load it and put on a quad. 500
and 500 are the original width and height of pic.

name = GL.GenTextures(1);

data = File.open("grass.jpg", "rb") {|io| io.read}

GL.PixelStorei(GL::UNPACK_ALIGNMENT, 1);

GL.BindTexture(GL::TEXTURE_2D, name[0]);

GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_S, GL::CLAMP);
GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_WRAP_T, GL::CLAMP);
GL.TexParameteri(GL::TEXTURE_2D,
GL::TEXTURE_MAG_FILTER,GL::NEAREST);
GL.TexParameteri(GL::TEXTURE_2D,
GL::TEXTURE_MIN_FILTER,GL::NEAREST);
GL.TexImage2D(GL::TEXTURE_2D, 0, GL::RGBA, 500,
500, 0, GL::RGBA, GL::UNSIGNED_BYTE,
data.unpack("C*"));


GL.BindTexture(GL::TEXTURE_2D,name[0]);
GL.Begin(GL::QUADS);
GL.TexCoord(0.0, 0.0); GL.Vertex(-20.0, 0.0, -20.0);
GL.TexCoord(0.0, 1.0); GL.Vertex(-20.0, 0.0, 20.0 );
GL.TexCoord(1.0, 1.0); GL.Vertex(20.0, 0.0, 20.0 );
GL.TexCoord(1.0, 0.0); GL.Vertex(20.0, 0.0, -20.0 );
GL.End();



The error I get:
Length of specified data doesn't correspond to format and type
parameters passed. Calculated length: 1000000 (ArgumentError)

As I think it may be due to the fact it contains more data, like width
and height in itself and the datatypes, just don't get it. By the way,
if I read it, it's still a string, why? Why do I have to pack/unpack?
thanks to every respond

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
+1 513-295-4739
Skype: rob.biedenharn
 
A

Alexandro Kez

Length of specified data doesn't correspond to format and type
parameters passed. Calculated length: 1000000 (ArgumentError)

Well I guess OpenGL uses integers and floats instead of Strings, I just
don't get it why ruby does.
 
A

Alexandro Kez

Oh, no... I really like ruby, but this is just ridiculous such a high
level language and no way to deal with such types of data?...


Rob said:
A jpeg is more complicated that that. (All image formats are actually.)

Here's http://gist.github.com/89738 some code that can find the width
and height of an image in PNG, GIF, or JPEG format. Notice how much
more complicated the JPEG code is because you have to find the right
JFIF segment and there can be embedded thumbnails and such so a simple
regexp search for the first part that looks like the size won't work.

You might want to look at ImageMagick (RMagick is the ruby interface)
or some other image library that will find the pixel data for you.

-Rob

GL.BindTexture(GL::TEXTURE_2D, name[0]);
Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
+1 513-295-4739
Skype: rob.biedenharn
 
P

Paul Smith

Oh, no... I really like ruby, but this is just ridiculous such a high
level language and no way to deal with such types of data?...

A JPEG is not a list of pixel values. That's a bitmap. JPEG uses
some awesome and very complex mathematics to compress the image size
without losing much in the way of photo quality. Ruby can cope with
JPEGs - you should look at the gist URL Rob provided or at RMagick.
 
C

Charles Johnson

Oh, no... I really like ruby, but this is just ridiculous such a high
level language and no way to deal with such types of data?...
The problem is not with ruby, but with the complexity of the .jpeg
format. RMagick has done all the hard work, but it depends on
installing ImageMagick. I use RMagick regularly, and installing
ImageMagick took a couple of false starts (I use both OSX and Ubuntu),
but in the end I got all the dependencies right. Then, RMagick "just
works." So, install ImageMagick and RMagick and impress your mates.

Or, learn to take apart the .jpeg from scratch.

Cheers--

Charles
 
R

Rob Biedenharn

Hello,



Well, rather than using RMagick which seem a bit complex at first
sight, you can always call 'convert' (from ImageMagick) with a system
call and transform your jpg in a text file:

jpg =3D "image.jpg"
txt =3D "image.txt"
system "convert #{jpg} #{txt}"

The image.txt file looks like

# ImageMagick pixel enumeration: 712,490,255,RGB
0,0: (226,188,115) #E2BC73 rgb(226,188,115)
1,0: (227,189,116) #E3BD74 rgb(227,189,116)
2,0: (226,188,115) #E2BC73 rgb(226,188,115)
...
709,489: (224,207,125) #E0CF7D rgb(224,207,125)
710,489: (211,203,120) #D3CB78 rgb(211,203,120)
711,489: (134,129, 45) #86812D rgb(134,129,45)

and its really easy to get the size (712x490) and the pixels colors
reading the file directly throught

File.open(txt) do |f|
f.readlines.each do |line|
# action on each line using regexp to get the colors
end
end

Cheers,

--=20
JJ Fleck
PCSI1 Lyc=E9e Kl=E9ber

Oh, new to me! I'm going to have to remember that one. I have to admit =20=

that I use Ruby system() calls to run various 'convert' operations =20
rather than go the RMagick route, too. Needing all the pixel data =20
might make it worth using RMagick, but you certainly can't get much =20
simpler that your image-as-text solution.

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
A

Alexandro Kez

Fleck, thanks for this really good answer, but could you tell then what
other data format may I use to avoid such parsings? I don't want to use
anything extra. Dunno about RMagick, but I've seen some rubyrames
example, where it's also done easy, but I wanna make it with ass few
external libs as possible, that's the idea - I wanna see if ruby "da
solo" is enough to coupe with such problems.
 
R

Rob Biedenharn

Fleck, thanks for this really good answer, but could you tell then
what
other data format may I use to avoid such parsings? I don't want to
use
anything extra. Dunno about RMagick, but I've seen some rubyrames
example, where it's also done easy, but I wanna make it with ass few
external libs as possible, that's the idea - I wanna see if ruby "da
solo" is enough to coupe with such problems.

Before you continue, perhaps you need to read from the OpenGL FAQ:

21.110 How can I turn my files, such as GIF, JPG, BMP, etc. into a
texture map?

http://www.opengl.org/resources/faq/technical/texture.htm#text0100

and the section that it references, too:

24.050 How can I save my OpenGL rendering as an image file, such as
GIF, TIF, JPG, BMP, etc.? How can I read these image files and use
them as texture maps?

http://www.opengl.org/resources/faq/technical/miscellaneous.htm#misc0050


So while you could use "ruby da solo", it's unlikely that you really
want to.

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
+1 513-295-4739
Skype: rob.biedenharn
 
A

Alexandro Kez

Yeah, ok, I know it's not part of OpenGL, so expected it to be done with
really high level language like ruby. I guess rubygame will work. Or I'd
just generate textures in code.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,164
Messages
2,570,901
Members
47,439
Latest member
elif2sghost

Latest Threads

Top