annotate graster/graster/lib/graster/image.rb @ 11:f952052e37b7

trying a fix.
author Robert McIntyre <rlm@mit.edu>
date Tue, 24 Aug 2010 19:06:45 -0400
parents
children
rev   line source
rlm@11 1 class Graster
rlm@11 2 class Image
rlm@11 3 PROPS = [:filename,:size,:pixels]
rlm@11 4
rlm@11 5 def initialize(props)
rlm@11 6 PROPS.each do |p|
rlm@11 7 raise "required image property :#{p} missing" unless props[p]
rlm@11 8 instance_variable_set "@#{p}", props[p]
rlm@11 9 end
rlm@11 10 end
rlm@11 11
rlm@11 12 PROPS.each{|p| attr_reader p }
rlm@11 13
rlm@11 14 def self.from_file pathname
rlm@11 15 raise "file not found #{pathname}" unless File.exist? pathname
rlm@11 16 img = Magick::Image.read(pathname)
rlm@11 17 raise "bad image data in #{pathname}" unless img = img[0]
rlm@11 18 new :filename => File.basename(pathname),
rlm@11 19 :size => [img.columns,img.rows],
rlm@11 20 :pixels => img.export_pixels(0,0,img.columns,img.rows,"I")
rlm@11 21 end
rlm@11 22
rlm@11 23 # get pixel(s) from x,y coords
rlm@11 24 # 0,0 is bottom,left
rlm@11 25 # image[x,y] => pixel at x,y
rlm@11 26 # image[y] => row at y
rlm@11 27 def [] y, x=nil
rlm@11 28 if x
rlm@11 29 @pixels[(@size[1]-y)*@size[0]+x]
rlm@11 30 else
rlm@11 31 @pixels[(@size[1]-y)*@size[0],@size[0]]
rlm@11 32 end
rlm@11 33 end
rlm@11 34
rlm@11 35 def each_row &block
rlm@11 36 @pixels.chars.each_slice(@size[0]).each_with_index &block
rlm@11 37 end
rlm@11 38
rlm@11 39 # "encode" a float 0..1 to a pixel
rlm@11 40 def self.f_to_pix f
rlm@11 41 (f*65535).round
rlm@11 42 end
rlm@11 43
rlm@11 44 # "decode" an encoded pixel to a float 0..1
rlm@11 45 def self.pix_to_f pix
rlm@11 46 pix/65535.0
rlm@11 47 end
rlm@11 48
rlm@11 49
rlm@11 50 # convert bitmap data to spans (or runs) of contiguous pixels
rlm@11 51 # also invert the Y axis
rlm@11 52 def build_spans on_range
rlm@11 53 # TODO: rewrite in terms of each_row
rlm@11 54 @spans = Array.new @size[1]
rlm@11 55
rlm@11 56 @size[1].times do |y|
rlm@11 57 spans = []
rlm@11 58 left = (@size[1]-y-1)*@size[0]
rlm@11 59 start = nil
rlm@11 60
rlm@11 61 @size[0].times do |x|
rlm@11 62 d = on_range.include?(@pixels[left+x])
rlm@11 63
rlm@11 64 if !start && d
rlm@11 65 start = x
rlm@11 66 elsif start && !d
rlm@11 67 spans << [start, x]
rlm@11 68 start = nil
rlm@11 69 end
rlm@11 70 end
rlm@11 71
rlm@11 72 spans << [start, @size[0]] if start
rlm@11 73 @spans[y] = spans
rlm@11 74 end
rlm@11 75 end
rlm@11 76
rlm@11 77 attr_reader :spans
rlm@11 78
rlm@11 79 def hash
rlm@11 80 [@pixels,@width,@height].hash
rlm@11 81 end
rlm@11 82 end
rlm@11 83 end