From: "Ara.T.Howard" Date: 2005-09-10T03:49:19+09:00 Subject: katrina images generated with ruby thought some of you out there might be interested in generating imagery with ruby, if so check out http://codeforpeople.com/katrina/fast/ the looper is java - but the individual images were generated from binary grids using this ruby program (the ENVI class is just a thin wrapper on narray which reads headers to determine types, etc.) file: katrina.rb #!/dmsp/reference/bin/ruby # # ara's lib # require 'alib' require 'mmap' require 'narray' require 'envi' # # main program class # class Main < ALib::SimpleMain version '0.0.0' author 'ara.t.howard@noaa.gov' usage <<-usage NAME #{ prognam } v#{ version } SYNOPSIS #{ prognam } [options]+ vis_grid tir_grid rgb_grid usage arguments 'vis_grid', 'tir_grid', 'rgb_grid' def main load_grids gen_rgb write_rgb write_rgb_header end def load_grids grid_opts = { 'cast' => 'int', 'mmap' => {'mode' => 'r', 'flags' => Mmap::MAP_SHARED} } @rg = ENVI::Grid::new vis_grid, grid_opts @gg = ENVI::Grid::new vis_grid, grid_opts @bg = ENVI::Grid::new tir_grid, grid_opts end def gen_rgb r = @rg.narray g = @gg.narray b = @bg.narray r[ (r.eq 255).where ] = 0 # hide missing g[ (g.eq 255).where ] = 0 # hide missing linear_stretch r, 7 .. 30 linear_stretch g, 7 .. 30 linear_stretch b, 175 .. 230 r[] = r * (1 << 24) g[] = g * (1 << 16) b[] = (255 - b) * (1 << 8) # invert blue channel @rgb = r | g | b @rgb = @rgb.hton r = g = b = nil end def linear_stretch na, irange, orange = (0..255) fna = NArray::float(*na.shape) fna[] = na imax, imin = irange.max, irange.min isize = imax - imin + 1 omax, omin = orange.max, orange.min osize = omax - omin + 1 # floor input lte_imin, gt_imin = (fna <= imin).where2 fna[ lte_imin ] = 0 fna[ gt_imin ] = fna[ gt_imin ] - imin + 1 # ceil input gt_imax = (fna > isize).where fna[ gt_imax ] = isize + 1 # percentage of in range fna[] = fna / (isize + 1) # scale into out range fna[] = fna * (osize - 1) na[] = fna end def write_rgb open(rgb_grid, 'w'){|f| f.write @rgb.to_s} end def write_rgb_header h = @rg.header open(rgb_grid + ".hdr", 'w') do |f| hdr = <<-hdr ENVI description = { R (#{ vis_grid }), G (#{ vis_grid }), B (#{ tir_grid }), A (alpha) } samples = #{ h.samples } lines = #{ h.lines } bands = 4 header offset = 0 file type = ENVI Standard data type = 1 interleave = bip sensor type = Unknown byte order = 1 map info = #{ h.map_info } wavelength units = Unknown default stretch = 0.000000 255.000000 linear data origin = NGDC band names = { R (Band 1:#{ vis_grid }), G (Band 2:#{ vis_grid }), B (Band 3:#{ tir_grid }), A (Band 4:alpha) } hdr hdr.each do |line| f.puts line.strip end end end end # # run unless included as a lib # Main::new.run if $0 == __FILE__ only takes about 3 seconds per image for 3001x3001 byte grids too ;-) the output images are raw and converted to jpg using something like (i forget syntax) convert -depth 8 -size 3001x3001 rgba:filename.rgba filename.jpg convert being and image magick utility. now that tim has made updates to im though - the narray/mmap could be used directy to set the pixels of an image from within ruby... i'll figure that out next week. ;-) -a -- =============================================================================== | email :: ara [dot] t [dot] howard [at] noaa [dot] gov | phone :: 303.497.6469 | Your life dwells amoung the causes of death | Like a lamp standing in a strong breeze. --Nagarjuna ===============================================================================