Guest User

RGSS Colorize HSL

a guest
Jul 16th, 2014
11
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2.  
  3. # ******************************************************************************
  4. # Hue / Saturation / Luminance
  5. # ******************************************************************************
  6. class HSL
  7.   attr_accessor :hue, :sat, :lum
  8.   def initialize(hue = 0, sat = 0, lum = 0)
  9.     @hue, @sat, @lum = hue, sat, lum
  10.   end
  11.  
  12.   def zero?
  13.     [@hue, @sat, @lum].all? {|f| f.abs < 0.0000001 }
  14.   end
  15.  
  16.   def hue2rgb(v1,v2,h)
  17.     h += 1 if h < 0
  18.     h -= 1 if h > 1
  19.     if ((6.0 * h) < 1)
  20.       return (v1 + (v2 - v1) * 6.0 * h)
  21.     elsif ((2 * h) < 1)
  22.       return v2
  23.     elsif ((3 * h) < 2)
  24.       return (v1 + (v2 - v1) * ((2.0/3.0) - h) * 6.0)
  25.     end
  26.     return v1
  27.   end
  28.   private :hue2rgb
  29.  
  30.   def to_color(a=255)
  31.     v1,v2 = 0.0,0.0
  32.     c = Color.new(0,0,0,0)
  33.     if @sat.zero?
  34.       c.set(*[@lum*255]*3,a)
  35.     else
  36.       if @lum < 0.5
  37.         v2 = @lum * (1.0 + @sat)
  38.       else
  39.         v2 = (@lum + @sat) - (@sat * @lum)
  40.       end
  41.       v1 = 2 * @lum - v2
  42.       c.red = 255 * hue2rgb(v1, v2, @hue + (1.0/3.0))
  43.       c.green = 255 * hue2rgb(v1, v2, @hue)
  44.       c.blue = 255 * hue2rgb(v1, v2, @hue - (1.0/3.0))
  45.     end
  46.     c.alpha = a
  47.     return c
  48.   end
  49.   alias saturation sat
  50.   alias luminance lum
  51. end
  52.  
  53. class Color
  54.   if !defined?(Color::Zero)
  55.     Zero = Color.new(0,0,0,0)
  56.   end
  57.  
  58.   # Get the brightness of a color, modified by the alpha
  59.   def brightness
  60.     ([red,green,blue].max * (alpha / 255.0)) / 255.0
  61.   end
  62.  
  63.   # Color packed into a long integer
  64.   def to_i
  65.     (alpha.round << 24 | red.round << 16 | green.round << 8 | blue.round)
  66.   end
  67.  
  68.   # Convert a color into it's hsl representation
  69.   def to_hsl
  70.     hsl = HSL.new
  71.     # get brightness of each color, and find the min, max, and difference (delta)
  72.     r,g,b = red/255.0, green/255.0, blue/255.0
  73.     min = [r, g, b].min
  74.     max = [r, g, b].max
  75.     del = max - min
  76.    
  77.     # Set the hsl's luminance to the average of min and max
  78.     hsl.lum = (max + min) / 2.0
  79.    
  80.     # if the delta is zero (min and max are same)
  81.     if del.zero?
  82.       hsl.hue = 0
  83.       hsl.sat = 0
  84.     else  # we are dealing with chromatic (varying color), not greyscale
  85.       if hsl.lum < 0.5
  86.         hsl.sat = del / (max + min)
  87.       else
  88.         hsl.sat = del / (2 - max - min)
  89.       end
  90.       # find the delta of each color
  91.       dr = (((max - r) / 6.0) + (del / 2.0)) / del
  92.       dg = (((max - g) / 6.0) + (del / 2.0)) / del
  93.       db = (((max - b) / 6.0) + (del / 2.0)) / del
  94.       # and define the hue by swapping the deltas around (basically)
  95.       if r == max
  96.         hsl.hue = db - dg
  97.       elsif g == max
  98.         hsl.hue = (1.0/3.0) + dr - db
  99.       elsif b == max
  100.         hsl.hue = (2.0/3.0) + dg - dr
  101.       end
  102.       # normalize the hue (0.0 to 1.0)
  103.       hsl.hue += 1 if hsl.hue < 0
  104.       hsl.hue -= 1 if hsl.hue > 1
  105.     end
  106.     return hsl
  107.   end
  108.  
  109.   def similar?(other_color, tolerance = 0, check_alpha = true)
  110.     delta = tolerance/2
  111.     bool = @red.between?(other_color.red-delta, other_color.red+delta) &&
  112.     @green.between?(other_color.green-delta, other_color.green+delta) &&
  113.     @blue.between?(other_color.blue-delta, other_color.blue+delta)
  114.     bool2 = true
  115.     if alpha_check
  116.       bool2 = @alpha.between?(other_color.alpha-delta, other_color.alpha+delta)
  117.     end
  118.     return (bool && bool2)
  119.   end
  120. end
  121.  
  122. class RecolorRule
  123.   attr_accessor :priority
  124.   attr_reader :tolerance, :from, :to, :current
  125.   def initialize(tolerance)
  126.     @priority = 0
  127.     @tolerance = tolerance
  128.     @current = nil
  129.   end
  130.  
  131.   def valid?(color)
  132.     false
  133.   end
  134.  
  135.   def exec(color)
  136.   end
  137. end
  138.  
  139. class White2Color < RecolorRule
  140.   attr_reader :color
  141.   def initialize(color, tolerance=128)
  142.     super(tolerance)
  143.     @color = color
  144.   end
  145.  
  146.   def valid?(color)
  147.     d = 1.0-(@tolerance/255.0)
  148.     hsl = color.to_hsl
  149.     hsl.lum >= d && hsl.sat <= 0.1 && color.alpha > 0
  150.   end
  151.  
  152.   def exec(color)
  153.     @color
  154.   end
  155. end
  156.  
  157. class Bitmap
  158.   attr_reader :colorized
  159.   def colorize(*rules)
  160.     dup.colorize!(*rules)
  161.   end
  162.   def colorize!(*rules)
  163.     rules = rules.flatten.compact
  164.     return self if rules.empty?
  165.     rules = rules.sort!(&:priority).reverse
  166.     @colorized = true
  167.     (0...height).each do |y|
  168.       (0...width).each do |x|
  169.         color = get_pixel(x, y)
  170.         rules.each do |rule|
  171.           next unless rule.valid?(color)
  172.           color = rule.exec(color)
  173.         end
  174.         set_pixel(x, y, color)
  175.       end
  176.     end
  177.     return self
  178.   end
  179. end
  180.  
  181. $sprites = Array.new(3) { Sprite.new }
  182.  
  183. # Setup background
  184. $sprites[0].bitmap = Bitmap.new(Graphics.width, Graphics.height).tap do |bg|
  185.   bg.fill_rect(bg.rect, Color.new(255, 255, 255, 255))
  186. end
  187.  
  188. # Setup rule, if tolerance isn't enough, up it
  189. rule = White2Color.new( Color.new(200, 0, 0, 255), 150 )
  190.  
  191. # Setup example sprites
  192. $sprites[1].bitmap = Bitmap.new("Code Off Image")
  193. $sprites[1].tap {|s| s.x = s.y = 200 }
  194. $sprites[2].bitmap = $sprites[1].bitmap.colorize(rule)
  195. $sprites[2].tap {|s| s.x = s.y = 300 }
  196.  
  197. loop do
  198.   Graphics.update
  199.   Input.update
  200.   $sprites.each(&:update)
  201.   break if Input.trigger?(:C)
  202. end
  203. $sprites.each do |s|
  204.   s.bitmap.dispose
  205.   s.dispose
  206. end
  207. exit
RAW Paste Data