Mercurial > lasercutter
diff 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 |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/graster/graster/lib/graster/image.rb Tue Aug 24 19:06:45 2010 -0400 1.3 @@ -0,0 +1,83 @@ 1.4 +class Graster 1.5 + class Image 1.6 + PROPS = [:filename,:size,:pixels] 1.7 + 1.8 + def initialize(props) 1.9 + PROPS.each do |p| 1.10 + raise "required image property :#{p} missing" unless props[p] 1.11 + instance_variable_set "@#{p}", props[p] 1.12 + end 1.13 + end 1.14 + 1.15 + PROPS.each{|p| attr_reader p } 1.16 + 1.17 + def self.from_file pathname 1.18 + raise "file not found #{pathname}" unless File.exist? pathname 1.19 + img = Magick::Image.read(pathname) 1.20 + raise "bad image data in #{pathname}" unless img = img[0] 1.21 + new :filename => File.basename(pathname), 1.22 + :size => [img.columns,img.rows], 1.23 + :pixels => img.export_pixels(0,0,img.columns,img.rows,"I") 1.24 + end 1.25 + 1.26 + # get pixel(s) from x,y coords 1.27 + # 0,0 is bottom,left 1.28 + # image[x,y] => pixel at x,y 1.29 + # image[y] => row at y 1.30 + def [] y, x=nil 1.31 + if x 1.32 + @pixels[(@size[1]-y)*@size[0]+x] 1.33 + else 1.34 + @pixels[(@size[1]-y)*@size[0],@size[0]] 1.35 + end 1.36 + end 1.37 + 1.38 + def each_row &block 1.39 + @pixels.chars.each_slice(@size[0]).each_with_index &block 1.40 + end 1.41 + 1.42 + # "encode" a float 0..1 to a pixel 1.43 + def self.f_to_pix f 1.44 + (f*65535).round 1.45 + end 1.46 + 1.47 + # "decode" an encoded pixel to a float 0..1 1.48 + def self.pix_to_f pix 1.49 + pix/65535.0 1.50 + end 1.51 + 1.52 + 1.53 + # convert bitmap data to spans (or runs) of contiguous pixels 1.54 + # also invert the Y axis 1.55 + def build_spans on_range 1.56 + # TODO: rewrite in terms of each_row 1.57 + @spans = Array.new @size[1] 1.58 + 1.59 + @size[1].times do |y| 1.60 + spans = [] 1.61 + left = (@size[1]-y-1)*@size[0] 1.62 + start = nil 1.63 + 1.64 + @size[0].times do |x| 1.65 + d = on_range.include?(@pixels[left+x]) 1.66 + 1.67 + if !start && d 1.68 + start = x 1.69 + elsif start && !d 1.70 + spans << [start, x] 1.71 + start = nil 1.72 + end 1.73 + end 1.74 + 1.75 + spans << [start, @size[0]] if start 1.76 + @spans[y] = spans 1.77 + end 1.78 + end 1.79 + 1.80 + attr_reader :spans 1.81 + 1.82 + def hash 1.83 + [@pixels,@width,@height].hash 1.84 + end 1.85 + end 1.86 +end 1.87 \ No newline at end of file