Reading Images

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?

2009/12/7 Alexandro K. [email protected]

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 = File.open(“foo.jpg”, “rb”) {|io| io.read}

Does that help?

Kind regards

robert

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

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

On Dec 7, 2009, at 11:05 AM, Alexandro K. wrote:

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

Rob B. http://agileconsultingllc.com
[email protected]
+1 513-295-4739
Skype: rob.biedenharn

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.

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

2009/12/7 Alexandro K. [email protected]:

GL.BindTexture(GL::TEXTURE_2D, name[0]);
GL.BindTexture(GL::TEXTURE_2D,name[0]);
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

On Dec 7, 2009, at 10:38 AM, Alexandro K. wrote:

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

On Mon, Dec 7, 2009 at 4:38 PM, Alexandro K. [email protected]
wrote:

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.

Paul S.
http://www.nomadicfun.co.uk

[email protected]

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 B. wrote:

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

On Dec 7, 2009, at 11:05 AM, Alexandro K. wrote:

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

Rob B. http://agileconsultingllc.com
[email protected]
+1 513-295-4739
Skype: rob.biedenharn

Hello,

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.

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 = “image.jpg”
txt = “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,

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.
Fleck Jean-Julien wrote:

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,

On Dec 7, 2009, at 1:03 PM, Fleck Jean-Julien wrote:

ImageMagick


JJ Fleck
PCSI1 Lycée Kléber

Oh, new to me! I’m going to have to remember that one. I have to admit
that I use Ruby system() calls to run various ‘convert’ operations
rather than go the RMagick route, too. Needing all the pixel data
might make it worth using RMagick, but you certainly can’t get much
simpler that your image-as-text solution.

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

On Dec 7, 2009, at 1:56 PM, Alexandro K. wrote:

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

710,489: (211,203,120) #D3CB78 rgb(211,203,120)

Cheers,

Posted via http://www.ruby-forum.com/.

Rob B. http://agileconsultingllc.com
[email protected]
+1 513-295-4739
Skype: rob.biedenharn

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.

So while you could use “ruby da solo”, it’s unlikely that you really
want to.

-Rob

710,489: (211,203,120) #D3CB78 rgb(211,203,120)

Cheers,

Posted via http://www.ruby-forum.com/.

Rob B. http://agileconsultingllc.com
[email protected]
+1 513-295-4739
Skype: rob.biedenharn