Module: PSD::Color

Extended by:
Color
Included in:
Color
Defined in:
lib/psd/color.rb

Overview

Various color conversion methods. All color values are stored in the PSD document in the color space as defined by the user instead of a normalized value of some kind. This means that we have to do all the conversion ourselves for each color space.

Constant Summary collapse

COLOR_SPACE =
{
  0 => :rgb,
  1 => :hsb,
  2 => :cmyk,
  7 => :lab,
  8 => :grayscale
}

Instance Method Summary collapse

Instance Method Details

#ahsb_to_color(alpha, hue, saturation, brightness) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/psd/color.rb', line 61

def ahsb_to_color(alpha, hue, saturation, brightness)
  if saturation == 0.0
    b = g = r = (255 * brightness).to_i
  else
    if brightness <= 0.5
      m2 = brightness * (1 + saturation)
    else
      m2 = brightness + saturation - brightness * saturation
    end

    m1 = 2 * brightness - m2
    r = hue_to_color(hue + 120, m1, m2)
    g = hue_to_color(hue, m1, m2)
    b = hue_to_color(hue - 120, m1, m2)
  end

  argb_to_color alpha, r, g, b
end

#alab_to_color(alpha, l, a, b) ⇒ Object



111
112
113
114
# File 'lib/psd/color.rb', line 111

def alab_to_color(alpha, l, a, b)
  xyz = lab_to_xyz(l, a, b)
  axyz_to_color alpha, xyz[0], xyz[1], xyz[2]
end

#argb_to_color(a, r, g, b) ⇒ Object



53
54
55
# File 'lib/psd/color.rb', line 53

def argb_to_color(a, r, g, b)
  (a << 24) | (r << 16) | (g << 8) | b
end

#cmyk_to_color(c, m, y, k) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
# File 'lib/psd/color.rb', line 95

def cmyk_to_color(c, m, y, k)
  r = 1 - (c * (1 - k) + k) * 255
  g = 1 - (m * (1 - k) + k) * 255
  b = 1 - (y * (1 - k) + k) * 255

  r = [0, r, 255].sort[1]
  g = [0, g, 255].sort[1]
  b = [0, b, 255].sort[1]

  rgb_to_color r, g, b
end

#cmyk_to_rgb(c, m, y, k) ⇒ Object



126
127
128
129
130
131
132
# File 'lib/psd/color.rb', line 126

def cmyk_to_rgb(c, m, y, k)
  Hash[{
    r: (65535 - (c * (255 - k) + (k << 8))) >> 8,
    g: (65535 - (m * (255 - k) + (k << 8))) >> 8,
    b: (65535 - (y * (255 - k) + (k << 8))) >> 8
  }.map { |k, v| [k, Util.clamp(v, 0, 255)] }]
end

#color_space_to_argb(color_space, color_component) ⇒ Object

In some places in the PSD file, colors are stored with a short that describes the color space, and the following 4 bytes that store the color data.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/psd/color.rb', line 20

def color_space_to_argb(color_space, color_component)
  color = case color_space
  when 0
    rgb_to_color *color_component
  when 1
    hsb_to_color color_component[0], 
      color_component[1] / 100.0, color_component[2] / 100.0
  when 2
    cmyk_to_color color_component[0] / 100.0,
      color_component[1] / 100.0, color_component[2] / 100.0,
      color_component[3] / 100.0
  when 7
    alab_to_color *color_component
  else
    0x00FFFFFF
  end

  color_to_argb(color)
end

#color_to_argb(color) ⇒ Object



40
41
42
43
44
45
46
47
# File 'lib/psd/color.rb', line 40

def color_to_argb(color)
  [
    (color) >> 24,
    ((color) & 0x00FF0000) >> 16,
    ((color) & 0x0000FF00) >> 8,
    (color) & 0x000000FF
  ]
end

#hsb_to_color(*args) ⇒ Object



57
58
59
# File 'lib/psd/color.rb', line 57

def hsb_to_color(*args)
  ahsb_to_color(255, *args)
end

#hue_to_color(hue, m1, m2) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/psd/color.rb', line 80

def hue_to_color(hue, m1, m2)
  hue = (hue % 360).to_i
  if hue < 60
    v = m1 + (m2 - m1) * hue / 60
  elsif hue < 180
    v = m2
  elsif hue < 240
    v = m1 + (m2 - m1) * (240 - hue) / 60
  else
    v = m1
  end

  (v * 255).to_i
end

#lab_to_color(*args) ⇒ Object



107
108
109
# File 'lib/psd/color.rb', line 107

def lab_to_color(*args)
  alab_to_color(255, *args)
end

#lab_to_xyz(l, a, b) ⇒ Object



116
117
118
119
120
121
122
123
124
# File 'lib/psd/color.rb', line 116

def lab_to_xyz(l, a, b)
  y = (l + 16) / 116
  x = y + (a / 500)
  z = y - (b / 200)

  x, y, z = [x, y, z].map do |n|
    n**3 > 0.008856 ? n**3 : (n - 16 / 116) / 7.787
  end
end

#rgb_to_color(*args) ⇒ Object



49
50
51
# File 'lib/psd/color.rb', line 49

def rgb_to_color(*args)
  argb_to_color(255, *args)
end