Skip to content
This repository
Newer
Older
100644 122 lines (103 sloc) 3.783 kb
224c3909 » rmagick
2003-08-28 Remove shebang line
1
2 # Usage: ruby histogram.rb [image filename]
3 # Purpose: draw an RGB histogram
4 # Notes: demonstrates Image#get_pixels method
5
6 require 'RMagick'
7
8 module Magick
9 class Image
10 HISTOGRAM_COLS = 256
11 HISTOGRAM_ROWS = 200
12
13 # Given a channel name and the frequency data for the
14 # channel, draw a histogram for the specified channel
15 def channel_histogram(color, freqs, scale, fg, bg)
16 histogram = Image.new(HISTOGRAM_COLS, HISTOGRAM_ROWS) {
17 self.background_color = bg
18 self.border_color = fg
19 }
20 gc = Draw.new
21 gc.stroke(color)
22 gc.stroke_width(1)
23
24 HISTOGRAM_COLS.times do |x|
25 gc.line(x, HISTOGRAM_ROWS, x, HISTOGRAM_ROWS-(freqs[x]*scale))
26 end
27 gc.draw(histogram)
28 return histogram
29 end
30 private :channel_histogram
31
32 # Draw histograms for each image channel plus a combined
33 # RGB histogram. Return the result as a single image.
34 def histogram(bg='black',fg='white')
35
36 # Count the level frequencies
37 red = Array.new(HISTOGRAM_COLS, 0)
38 green = Array.new(HISTOGRAM_COLS, 0)
39 blue = Array.new(HISTOGRAM_COLS, 0)
40
41 rows.times do |row|
42 pixels = get_pixels(0, row, columns, 1)
43 pixels.each do |pixel|
44 v = pixel.red & 0xff
45 red[v] = red[v].succ
46 v = pixel.green & 0xff
47 green[v] = green[v].succ
48 v = pixel.blue & 0xff
49 blue[v] = blue[v].succ
50 end
51 end
52
53 # Compute the maximum frequency. Scale to chart size.
54 max = 0
55 HISTOGRAM_COLS.times do |x|
56 max = [red[x], green[x], blue[x], max].max
57 end
58
59 # When computing the scale, add 5% "air" between
60 # the max frequency and the top of the histogram.
61 # This makes a prettier chart.
62 scale = HISTOGRAM_ROWS / (max*1.05)
63
64 # Draw the R, G, B and combined histograms.
65 charts = ImageList.new
66 charts << channel_histogram('red', red, scale, fg, bg)
67 charts << channel_histogram('rgb(0,255,0)', green, scale, fg, bg)
68 charts << channel_histogram('blue', blue, scale, fg, bg)
69 rgb = charts[0].composite(charts[1], CenterGravity, PlusCompositeOp)
70 rgb = rgb.composite(charts[2], CenterGravity, PlusCompositeOp)
71 charts.unshift(rgb)
72
73 # Make a montage.
74 histogram = charts.montage {
75 self.background_color = bg
76 self.border_width = 1
77 self.tile = "2x2"
78 self.geometry = "+10+15"
79 self.stroke = 'transparent'
80 }
81
82 # Add the filename in the middle.
83 filename = Draw.new
84 filename.annotate(histogram, 0, 0, 0, 0, self.filename) {
85 self.stroke = 'transparent'
86 self.fill = fg
87 self.gravity = CenterGravity
88 }
89 return histogram
90 end
91 end
92 end
93
94 if !ARGV[0] || ARGV[0] == '-?' then
95 puts "Usage: histogram.rb <image-file>"
96 exit
97 end
98
99 image = Magick::Image.read(ARGV[0])
100 if image.length > 1
101 puts "Charting 1st image"
102 end
103 image = image.first
104
105 name = File.basename(ARGV[0])
106 name.sub!(/\..*$/,'')
107 $defout.sync = true
108 printf "Creating #{name}_Histogram.gif..."
109
110 timer = Thread.new do
111 loop do
112 sleep(1)
113 printf "."
114 end
115 end
116
117 histogram = image.histogram
118
119 histogram.write("./#{name}_Histogram.gif")
120 Thread.kill(timer)
121 puts "Done!"
122 exit
Something went wrong with that request. Please try again.