Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # ******************************************************************************
- # Hue / Saturation / Luminance
- # ******************************************************************************
- class HSL
- attr_accessor :hue, :sat, :lum
- def initialize(hue = 0, sat = 0, lum = 0)
- @hue, @sat, @lum = hue, sat, lum
- end
- def zero?
- [@hue, @sat, @lum].all? {|f| f.abs < 0.0000001 }
- end
- def hue2rgb(v1,v2,h)
- h += 1 if h < 0
- h -= 1 if h > 1
- if ((6.0 * h) < 1)
- return (v1 + (v2 - v1) * 6.0 * h)
- elsif ((2 * h) < 1)
- return v2
- elsif ((3 * h) < 2)
- return (v1 + (v2 - v1) * ((2.0/3.0) - h) * 6.0)
- end
- return v1
- end
- private :hue2rgb
- def to_color(a=255)
- v1,v2 = 0.0,0.0
- c = Color.new(0,0,0,0)
- if @sat.zero?
- c.set(*[@lum*255]*3,a)
- else
- if @lum < 0.5
- v2 = @lum * (1.0 + @sat)
- else
- v2 = (@lum + @sat) - (@sat * @lum)
- end
- v1 = 2 * @lum - v2
- c.red = 255 * hue2rgb(v1, v2, @hue + (1.0/3.0))
- c.green = 255 * hue2rgb(v1, v2, @hue)
- c.blue = 255 * hue2rgb(v1, v2, @hue - (1.0/3.0))
- end
- c.alpha = a
- return c
- end
- alias saturation sat
- alias luminance lum
- end
- class Color
- if !defined?(Color::Zero)
- Zero = Color.new(0,0,0,0)
- end
- # Get the brightness of a color, modified by the alpha
- def brightness
- ([red,green,blue].max * (alpha / 255.0)) / 255.0
- end
- # Color packed into a long integer
- def to_i
- (alpha.round << 24 | red.round << 16 | green.round << 8 | blue.round)
- end
- # Convert a color into it's hsl representation
- def to_hsl
- hsl = HSL.new
- # get brightness of each color, and find the min, max, and difference (delta)
- r,g,b = red/255.0, green/255.0, blue/255.0
- min = [r, g, b].min
- max = [r, g, b].max
- del = max - min
- # Set the hsl's luminance to the average of min and max
- hsl.lum = (max + min) / 2.0
- # if the delta is zero (min and max are same)
- if del.zero?
- hsl.hue = 0
- hsl.sat = 0
- else # we are dealing with chromatic (varying color), not greyscale
- if hsl.lum < 0.5
- hsl.sat = del / (max + min)
- else
- hsl.sat = del / (2 - max - min)
- end
- # find the delta of each color
- dr = (((max - r) / 6.0) + (del / 2.0)) / del
- dg = (((max - g) / 6.0) + (del / 2.0)) / del
- db = (((max - b) / 6.0) + (del / 2.0)) / del
- # and define the hue by swapping the deltas around (basically)
- if r == max
- hsl.hue = db - dg
- elsif g == max
- hsl.hue = (1.0/3.0) + dr - db
- elsif b == max
- hsl.hue = (2.0/3.0) + dg - dr
- end
- # normalize the hue (0.0 to 1.0)
- hsl.hue += 1 if hsl.hue < 0
- hsl.hue -= 1 if hsl.hue > 1
- end
- return hsl
- end
- def similar?(other_color, tolerance = 0, check_alpha = true)
- delta = tolerance/2
- bool = @red.between?(other_color.red-delta, other_color.red+delta) &&
- @green.between?(other_color.green-delta, other_color.green+delta) &&
- @blue.between?(other_color.blue-delta, other_color.blue+delta)
- bool2 = true
- if alpha_check
- bool2 = @alpha.between?(other_color.alpha-delta, other_color.alpha+delta)
- end
- return (bool && bool2)
- end
- end
- class RecolorRule
- attr_accessor :priority
- attr_reader :tolerance, :from, :to, :current
- def initialize(tolerance)
- @priority = 0
- @tolerance = tolerance
- @current = nil
- end
- def valid?(color)
- false
- end
- def exec(color)
- end
- end
- class White2Color < RecolorRule
- attr_reader :color
- def initialize(color, tolerance=128)
- super(tolerance)
- @color = color
- end
- def valid?(color)
- d = 1.0-(@tolerance/255.0)
- hsl = color.to_hsl
- hsl.lum >= d && hsl.sat <= 0.1 && color.alpha > 0
- end
- def exec(color)
- @color
- end
- end
- class Bitmap
- attr_reader :colorized
- def colorize(*rules)
- dup.colorize!(*rules)
- end
- def colorize!(*rules)
- rules = rules.flatten.compact
- return self if rules.empty?
- rules = rules.sort!(&:priority).reverse
- @colorized = true
- (0...height).each do |y|
- (0...width).each do |x|
- color = get_pixel(x, y)
- rules.each do |rule|
- next unless rule.valid?(color)
- color = rule.exec(color)
- end
- set_pixel(x, y, color)
- end
- end
- return self
- end
- end
- $sprites = Array.new(3) { Sprite.new }
- # Setup background
- $sprites[0].bitmap = Bitmap.new(Graphics.width, Graphics.height).tap do |bg|
- bg.fill_rect(bg.rect, Color.new(255, 255, 255, 255))
- end
- # Setup rule, if tolerance isn't enough, up it
- rule = White2Color.new( Color.new(200, 0, 0, 255), 150 )
- # Setup example sprites
- $sprites[1].bitmap = Bitmap.new("Code Off Image")
- $sprites[1].tap {|s| s.x = s.y = 200 }
- $sprites[2].bitmap = $sprites[1].bitmap.colorize(rule)
- $sprites[2].tap {|s| s.x = s.y = 300 }
- loop do
- Graphics.update
- Input.update
- $sprites.each(&:update)
- break if Input.trigger?(:C)
- end
- $sprites.each do |s|
- s.bitmap.dispose
- s.dispose
- end
- exit
RAW Paste Data