graphics lib?

A

Alwin Blok

Hello,

What would be the best choice for 2d vector graphics with ruby?
My needs are as follows:
2D vector (SVG/ pdf/ postscript like), Animation, Offscreen rendering.

I think i'll use openGL, but I'd rather use a pure 2D oriented library.
I've searched raa, but could not find anything like that.
Is there any 2D vector lib I should know about, or is opengl my only
option? (as long as i want to use ruby)

Regards Alwin.
 
C

Charles Comstock

Simon said:
I can recommend RMagic.
http://rmagick.rubyforge.org/

Don't know about animation though.


You may see what I have made using RMagick, here:
http://aeditor.rubyforge.org/softwrap.html

I have used RMagic in the past, but it doesn't quite seem suited to per
pixel editing. I was trying to do an AI project of RedEye detection for
a class, and I did succeed to use it but I had to add a couple methods
to more easily edit individual pixels. It just didn't seem to be really
set up to do per pixel calculations or modifications very nicely. I was
curious if anyone else has suggestions on what would be most
appropriate for that?

Charles Comstock
 
D

denis

Alwin Blok said:
Hello,

What would be the best choice for 2d vector graphics with ruby?
My needs are as follows:
2D vector (SVG/ pdf/ postscript like), Animation, Offscreen rendering.

I think i'll use openGL, but I'd rather use a pure 2D oriented library.
I've searched raa, but could not find anything like that.
Is there any 2D vector lib I should know about, or is opengl my only
option? (as long as i want to use ruby)

Regards Alwin.

libplot from the gnu plotutils project could be a good choice for you.
There are ruby bindings here, but i dont known how complete they are.

http://raa.ruby-lang.org/list.rhtml?name=ruby-libplot

Ciao

Denis
 
S

Simon Strandgaard

I have used RMagic in the past, but it doesn't quite seem suited to per
pixel editing. I was trying to do an AI project of RedEye detection for
a class, and I did succeed to use it but I had to add a couple methods
to more easily edit individual pixels. It just didn't seem to be really
set up to do per pixel calculations or modifications very nicely. I was
curious if anyone else has suggestions on what would be most
appropriate for that?


It's possible with RMagick.. get/set pixel methods :)
http://www.simplesystems.org/RMagick/doc/image.html#Image.get_pixels
 
C

Charles Comstock

Simon said:

Right I have used that function it's just very cumbersome, it would be
much easier to directly edit the values in the real array they are in.
Exporting a pixel array is really not a very efficient operation, not to
mention the need to reimport them later. Not to mention the fact it
returns a flat array which while it's easy to write an accessor that
2d's it, it still is not particularly friendly towards doing image analysis.

Charlie
 
H

Hal Fulton

Charles said:
Right I have used that function it's just very cumbersome, it would be
much easier to directly edit the values in the real array they are in.
Exporting a pixel array is really not a very efficient operation, not to
mention the need to reimport them later. Not to mention the fact it
returns a flat array which while it's easy to write an accessor that
2d's it, it still is not particularly friendly towards doing image
analysis.

Tell that to Tim. I'm sure he'll consider adding to the API if you
make a strong case for it.

Hal
 
A

Ara.T.Howard

Date: Mon, 02 Feb 2004 18:27:32 -0600
From: Charles Comstock <[email protected]>
Newsgroups: comp.lang.ruby
Subject: Re: graphics lib?



Right I have used that function it's just very cumbersome, it would be
much easier to directly edit the values in the real array they are in.
Exporting a pixel array is really not a very efficient operation, not to
mention the need to reimport them later. Not to mention the fact it
returns a flat array which while it's easy to write an accessor that
2d's it, it still is not particularly friendly towards doing image analysis.

Charlie

i'm in total agreement. what i have done is to create a class the memory maps
images using guy's mmap module in 'r+' mode (read/write) and created a class
that '2ds' the pixel indexes - using this i have written some ruby programs
which run faster that some of our C programs (due to stupid i/o ops). if you
really are doing pixel level operations i'd consider this approach.

-a
--

ATTN: please update your address books with address below!

===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| STP :: http://www.ngdc.noaa.gov/stp/
| NGDC :: http://www.ngdc.noaa.gov/
| NESDIS :: http://www.nesdis.noaa.gov/
| NOAA :: http://www.noaa.gov/
| US DOC :: http://www.commerce.gov/
|
| The difference between art and science is that science is what we
| understand well enough to explain to a computer.
| Art is everything else.
| -- Donald Knuth, "Discover"
|
| /bin/sh -c 'for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done'
===============================================================================
 
C

Charles Comstock

Ara.T.Howard said:
i'm in total agreement. what i have done is to create a class the memory maps
images using guy's mmap module in 'r+' mode (read/write) and created a class
that '2ds' the pixel indexes - using this i have written some ruby programs
which run faster that some of our C programs (due to stupid i/o ops). if you
really are doing pixel level operations i'd consider this approach.

-a

You don't happen to have some code for example of this? I'm not quite
following is this through a C extension or just raw ruby? My solution I
did last time was wrap the get/set pixel methods so they only grabbed
a 1x1 range, and then I could access them directly, but this somehow
seems like it probably incites horrible performance.
Charles Comstock
 
T

Tim Hunter

Tell that to Tim. I'm sure he'll consider adding to the API if you make a
strong case for it.

Or even a weak case :)

Suggestions and patches are always welcome. I'm planning a new release of
RMagick in conjunction with the upcoming release of ImageMagick 5.5.8.
 
A

Ara.T.Howard

You don't happen to have some code for example of this? I'm not quite
following is this through a C extension or just raw ruby? My solution I did
last time was wrap the get/set pixel methods so they only grabbed a 1x1
range, and then I could access them directly, but this somehow seems like it
probably incites horrible performance.
Charles Comstock

before i reply to the above i'd also suggest checking out narray - it features
ultra fast and pretty easy to use very large array manipulation. it is a c
extension available from the raa...

re: above

yes - i have example code - and yes mmap is a c extension (written by ts). my
code is ultra specific to a statelite image format we use here at ngdc that's
something like

number of records = 3021
number of header records = 1
number of data records = 3020
record size = 7231
...
...
...
...
...
lots_of_binary_satelite_data32409132483124083209840238402983.....
409132483124083209840238402983.....
409132483124083209840238402983.....

i have classes for header, scanlines, scanline header, and to get at
row/pixels.

excerpt follows (contact me offline and i will send you sources); this should
give you the general flavor of what i'm talking about. below shows the idea
behind a row level 'munging' method (#map!) that makes use of mmap to change
pixels in place w/o really doing anything explict. pixel operations would be
similar. the speed is gained by mapping the file 'rw' and never hanging on to
more data than required at a time - in this case a scanline (record) of data.

# RAA
require 'mmap'

....

module DMSP
module OLS
class Header < Array
#{{{
....
....
def [] k
#{{{
idx = index_of k
raise IndexError, "#{ k.class } : #{ k.inspect }" unless idx

ret = super(idx)
raise IndexError, "#{ k.class } : #{ k.inspect }" unless
ret and ret.size == 2

Numeric === k ? ret : ret[1]
#}}}
end
# new
....
def []= k, v
#{{{
if Numeric === k
raise TypeError, "#{ v.class } : #{ v.inspect }" unless Array === v
@modified = true
return super(k,v)
end

idx = index_of k

if idx
k = self[idx].first if Regexp === k
else
raise IndexError, "#{ k.class } : #{ k.inspect }" if Regexp === k
idx = self.size # append
end

raise TypeError, "#{ k.class } : #{ k.inspect }" unless String === k

pair = [k.strip, v]
# recurse with numeric argument!
self[idx] = pair
v
#}}}
end
....
#}}}
end # class Header

class Mmap < ::Mmap
#{{{
....
....
# methods
def initialize(*args)
#{{{
@args = DMSP::hashify(*args)

@path, @mode, @protection =
@args.values_at :path, :mode, :protection

@type = DMSP::file_type @path

@mode ||= DEFAULT_MODE
@protection ||= DEFAULT_PROTECTION

super(path, mode, protection)

@header = Header.new :io => self

self
#}}}
end
....
def get_record n
#{{{
n = n.to_i
raise(IndexError, "INDEX [%s]" % [n]) if
n < 0 or n >= number_of_records

rb = header.record_bytes

start, length = n * rb, rb

self[start, length]
#}}}
end
....
def set_record n, data
#{{{
n = n.to_i
raise(IndexError, "INDEX [%s]" % [n]) if
n < 0 or n >= number_of_records

rb = header.record_bytes

raise(RangeError, "DATA SIZE [%d]" % [data.size]) if
data.size != rb

start, length = n * rb, rb

self[start, length] = data
#}}}
end
....
def map!
#{{{
changed = false
r = header.number_of_header_records ... header.number_of_records

r.each do |n|
data = yield(get_record(n))
if data
set_record(n, data)
changed = true
end
end

changed ? self : nil
#}}}
end
alias collect! map!
....
#}}}
end # class MmappedFile
end # module DMSP


i would think that, for an image, you may end up with something like
(un-tested)

class Image < Mmap
# class to support double ([j]) style indexing
class Row
attr :row
attr :image
def initialize row, image; @row = row; @image = image; end
def [] col
image[row * image.n_cols + col]
end
def []= col, pixel
image[row * image.n_cols + col] = pixel
end
end

attr :n_rows
attr :n_cols
def initialize path, n_rows, n_cols
super path, 'rw', Mmap::MAP_SHARED
end
def [] row
Row.new row, self
end
def pixel i, j, pix = nil
pix ? (self[i * n_cols + j] = pix) : self[i * n_cols + j]
end
end

which would allow you to do something like

p(image.pixel i, j)
image.pixel i, j, 0b101010
p(image.pixel i, j)

or

p(image.pixel[j])
image.pixel[j] = 0b101010
p(image.pixel[j])



you would proably be better off using rmagick or narray. the reason i chose
this approach is that the ONLY thing i really needed was pixel level access
since we are applying our own algorithims to the pixels and installing rmagick
or narray for this was a bit overkill. mmap is lightweight and fast if all
you desire is pixel level access.

food for thought.


-a
--

ATTN: please update your address books with address below!

===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| STP :: http://www.ngdc.noaa.gov/stp/
| NGDC :: http://www.ngdc.noaa.gov/
| NESDIS :: http://www.nesdis.noaa.gov/
| NOAA :: http://www.noaa.gov/
| US DOC :: http://www.commerce.gov/
|
| The difference between art and science is that science is what we
| understand well enough to explain to a computer.
| Art is everything else.
| -- Donald Knuth, "Discover"
|
| /bin/sh -c 'for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done'
===============================================================================
 

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

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,150
Latest member
MakersCBDReviews
Top