Class Color::Palette::AdobeColor
In: lib/color/palette/adobecolor.rb
Parent: Object
Enumerable Gimp AdobeColor CMYK\n[lib/color.rb\nlib/color/cmyk.rb] GrayScale\n[lib/color.rb\nlib/color/grayscale.rb] RGB\n[lib/color.rb\nlib/color/rgb-colors.rb\nlib/color/rgb.rb] YIQ\n[lib/color.rb\nlib/color/yiq.rb] HSL MonoContrast lib/color/cmyk.rb lib/color/grayscale.rb lib/color/rgb.rb lib/color/yiq.rb lib/color/hsl.rb CSS lib/color/palette/gimp.rb lib/color/palette/adobecolor.rb lib/color/palette/monocontrast.rb Palette Color dot/m_10_0.png

A class that can read an Adobe Color palette file (used for Photoshop swatches) and provide a Hash-like interface to the contents. Not all colour formats in ACO files are supported. Based largely off the information found by Larry Tesler.

Not all Adobe Color files have named colours; all named entries are returned as an array.

  pal = Color::Palette::AdobeColor.from_file(my_aco_palette)
  pal[0]          => Color::RGB<...>
  pal["white"]    => [ Color::RGB<...> ]
  pal["unknown"]  => [ Color::RGB<...>, Color::RGB<...>, ... ]

AdobeColor palettes are always indexable by insertion order (an integer key).

Version 2 palettes use UTF-16 colour names.

Methods

[]   each   each_name   from_file   from_io   new   size   values_at  

Included Modules

Enumerable

Attributes

lost  [R]  Contains the "lost" colours in the palette. These colours could not be properly loaded (e.g., L*a*b* is not supported by Color, so it is "lost") or are not understood by the algorithms.
statistics  [R]  Returns statistics about the nature of the colours loaded.
version  [R] 

Public Class methods

Create an AdobeColor palette object from the named file.

[Source]

    # File lib/color/palette/adobecolor.rb, line 39
39:     def from_file(filename)
40:       File.open(filename, "rb") { |io| Color::Palette::AdobeColor.from_io(io) }
41:     end

Create an AdobeColor palette object from the provided IO.

[Source]

    # File lib/color/palette/adobecolor.rb, line 44
44:     def from_io(io)
45:       Color::Palette::AdobeColor.new(io.read)
46:     end

Create a new AdobeColor palette from the palette file as a string.

[Source]

     # File lib/color/palette/adobecolor.rb, line 60
 60:   def initialize(palette)
 61:     @colors     = []
 62:     @names      = {}
 63:     @statistics = Hash.new(0)
 64:     @lost       = []
 65:     @order      = []
 66:     @version    = nil
 67: 
 68:     class << palette
 69:       def readwords(count = 1)
 70:         @offset ||= 0
 71:         raise IndexError if @offset >= self.size
 72:         val = self[@offset, count * 2]
 73:         raise IndexError if val.nil? or val.size < (count * 2)
 74:         val = val.unpack("n" * count)
 75:         @offset += count * 2
 76:         val
 77:       end
 78: 
 79:       def readutf16(count = 1)
 80:         @offset ||= 0
 81:         raise IndexError if @offset >= self.size
 82:         val = self[@offset, count * 2]
 83:         raise IndexError if val.nil? or val.size < (count * 2)
 84:         @offset += count * 2
 85:         val
 86:       end
 87:     end
 88: 
 89:     @version, count = palette.readwords 2
 90: 
 91:     raise "Unknown AdobeColor palette version #@version." unless @version.between?(1, 2)
 92: 
 93:     count.times do
 94:       space, w, x, y, z = palette.readwords 5
 95:       name = nil
 96:       if @version == 2
 97:         raise IndexError unless palette.readwords == [ 0 ]
 98:         len = palette.readwords
 99:         name = palette.readutf16(len[0] - 1)
100:         raise IndexError unless palette.readwords == [ 0 ]
101:       end
102: 
103:       color = case space
104:               when 0 then # RGB
105:                 @statistics[:rgb] += 1
106: 
107:                 Color::RGB.new(w / 256, x / 256, y / 256)
108:               when 1 then # HS[BV] -- Convert to RGB
109:                 @statistics[:hsb] += 1
110: 
111:                 h = w / 65535.0
112:                 s = x / 65535.0
113:                 v = y / 65535.0
114: 
115:                 if defined?(Color::HSB)
116:                   Color::HSB.from_fraction(h, s, v)
117:                 else
118:                   @statistics[:converted] += 1
119:                   if Color.near_zero_or_less?(s)
120:                     Color::RGB.from_fraction(v, v, v)
121:                   else
122:                     if Color.near_one_or_more?(h)
123:                       vh = 0
124:                     else
125:                       vh = h * 6.0
126:                     end
127: 
128:                     vi = vh.floor
129:                     v1 = v.to_f * (1 - s.to_f)
130:                     v2 = v.to_f * (1 - s.to_f * (vh - vi))
131:                     v3 = v.to_f * (1 - s.to_f * (1 - (vh - vi)))
132: 
133:                     case vi
134:                     when 0 then Color::RGB.from_fraction(v, v3, v1)
135:                     when 1 then Color::RGB.from_fraction(v2, v, v1)
136:                     when 2 then Color::RGB.from_fraction(v1, v, v3)
137:                     when 3 then Color::RGB.from_fraction(v1, v2, v)
138:                     when 4 then Color::RGB.from_fraction(v3, v1, v)
139:                     else Color::RGB.from_fraction(v, v1, v2)
140:                     end
141:                   end
142:                 end
143:               when 2 then # CMYK
144:                 @statistics[:cmyk] += 1
145:                 Color::CMYK.from_percent(100 - (w / 655.35),
146:                                          100 - (x / 655.35),
147:                                          100 - (y / 655.35),
148:                                          100 - (z / 655.35))
149:               when 7 then # L*a*b*
150:                 @statistics[:lab] += 1
151: 
152:                 l = [w, 10000].min / 100.0
153:                 a = [[-12800, UwToSw[x]].max, 12700].min / 100.0
154:                 b = [[-12800, UwToSw[x]].max, 12700].min / 100.0
155: 
156:                 if defined? Color::Lab
157:                   Color::Lab.new(l, a, b)
158:                 else
159:                   [ space, w, x, y, z ]
160:                 end
161:               when 8 then # Grayscale
162:                 @statistics[:gray] += 1
163: 
164:                 g = [w, 10000].min / 100.0
165:                 Color::GrayScale.new(g)
166:               when 9 then # Wide CMYK
167:                 @statistics[:wcmyk] += 1
168: 
169:                 c = [w, 10000].min / 100.0
170:                 m = [x, 10000].min / 100.0
171:                 y = [y, 10000].min / 100.0
172:                 k = [z, 10000].min / 100.0
173:                 Color::CMYK.from_percent(c, m, y, k)
174:               else
175:                 @statistics[space] += 1
176:                 [ space, w, x, y, z ]
177:               end
178: 
179:       @order << [ color, name ]
180: 
181:       if color.kind_of? Array
182:         @lost << color
183:       else
184:         @colors << color
185: 
186:         if name
187:           @names[name] ||= []
188:           @names[name] << color
189:         end
190:       end
191:     end
192:   end

Public Instance methods

If a Numeric key is provided, the single colour value at that position will be returned. If a String key is provided, the colour set (an array) for that colour name will be returned.

[Source]

     # File lib/color/palette/adobecolor.rb, line 202
202:   def [](key)
203:     if key.kind_of?(Numeric)
204:       @colors[key]
205:     else
206:       @names[key]
207:     end
208:   end

Loops through each colour.

[Source]

     # File lib/color/palette/adobecolor.rb, line 211
211:   def each
212:     @colors.each { |el| yield el }
213:   end

Loops through each named colour set.

[Source]

     # File lib/color/palette/adobecolor.rb, line 216
216:   def each_name #:yields color_name, color_set:#
217:     @names.each { |color_name, color_set| yield color_name, color_set }
218:   end

[Source]

     # File lib/color/palette/adobecolor.rb, line 220
220:   def size
221:     @colors.size
222:   end

Provides the colour or colours at the provided selectors.

[Source]

     # File lib/color/palette/adobecolor.rb, line 195
195:   def values_at(*selectors)
196:     @colors.values_at(*selectors)
197:   end

[Validate]