An obfuscated image, which draws the letters of a key string at random offsets against a noisy background.
this is the only way to create an image of this sort, since ‘new’ is private. This is because of the way the Ruby/GD module implements the GD::Image class… you can’t override it by providing an ‘initialize’ method.
- key: the key string to display
- font: the font to display the key in. This should be a path to a font file.
- font_size: the size (in points) that the key string should be displayed
- x_spacing: how much space to insert between characters
- max_wiggle_y: the maximum "wiggle" for each character in y
- rotation: the maximum angle of rotation for each character.
[ show source ]
# File lib/captcha.rb, line 112
112: def ObfuscatedImage.create( key, font, font_size, x_spacing, max_wiggle_y, rotation )
113: width, height = 0, 0
114:
115: key.each_byte do |byte|
116: char = byte.chr
117:
118: err, bounds = GD::Image.stringFT( 0, font, font_size, 0, 0, 0, char )
119: raise err if err
120:
121: bounds = Rectangle.from_array( bounds )
122:
123: width += bounds.width
124: height = bounds.height if height < bounds.height
125: end
126:
127: char_height = height
128:
129: extra_x = x_spacing * ( key.length + 1 )
130: extra_y = max_wiggle_y
131:
132: width += extra_x
133: height += extra_y
134:
135: image = new( width, height )
136: image.initialize_image( key, font, font_size, x_spacing, max_wiggle_y, char_height, rotation )
137:
138: return image
139: end
clear the image background to white.
[ show source ]
# File lib/captcha.rb, line 159
159: def clear_background
160: white = colorResolve( 255, 255, 255 )
161: filledRectangle( 0, 0, width, height, white )
162: end
draw the key string on the image, randomly positioning each character.
[ show source ]
# File lib/captcha.rb, line 180
180: def draw_key
181: black = colorResolve( 0, 0, 0 )
182: x = @x_spacing
183:
184: @key.each_byte do |b|
185: c = b.chr
186: y = rand( 3*@wiggle_y/4 ) + @char_height
187:
188: # compute the unrotated bounds, for determing how to increment
189: err, bounds = GD::Image.stringFT( 0, @font, @font_size, 0, 0, 0, c )
190: rect = Rectangle.from_array( bounds )
191:
192: # draw the character
193: stringFT( black, @font, @font_size,
194: Math::PI*(rand(@rotation)-@rotation/2)/180.0,
195: x, y, c )
196:
197: x += rect.width + @x_spacing
198: end
199: end
The ‘initialize’ method for an ObfuscatedImage. The parameters are the same as for the create method, with the addition of char_height (which represents the maximum height of any character in the string).
[ show source ]
# File lib/captcha.rb, line 144
144: def initialize_image( key, font, font_size, x_spacing, wiggle_y, char_height, rotation )
145: @key = key
146: @font = font
147: @font_size = font_size
148: @x_spacing = x_spacing
149: @wiggle_y = wiggle_y
150: @char_height = char_height
151: @rotation = rotation
152:
153: clear_background
154: populate_with_noise
155: draw_key
156: end
populate the image with random noise
[ show source ]
# File lib/captcha.rb, line 165
165: def populate_with_noise
166: color = colorResolve( 0, 0, 0 )
167:
168: ( width * height / 4 ).times do
169: x, y = rand( width ), rand( height )
170: setPixel( x, y, color )
171: end
172:
173: inc = height/10
174: ( height / inc ).times do |i|
175: line( 0, inc*i + rand(20) - 10, width, inc*i + rand(20) - 10, color )
176: end
177: end