Class: Magick::Pixel

Inherits:
Object
  • Object
show all
Includes:
Comparable, Observable
Defined in:
lib/rmagick4j/pixel.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(red = 0, green = 0, blue = 0, opacity = 0) ⇒ Pixel

Returns a new instance of Pixel.



20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/rmagick4j/pixel.rb', line 20

def initialize(red=0, green=0, blue=0, opacity=0)
  # TODO: I think PixelPacket should be int-based (Pixel requires argument
  # conversion, but PixelPacket requires us to reconvert to double (see
  # to_f below).  This is a bunch of work.
  red = type_check(red, :to_int, "Integer")
  green = type_check(green, :to_int, "Integer")
  blue = type_check(blue, :to_int, "Integer")
  opacity = type_check(opacity, :to_int, "Integer")

  # TODO: Add support to CMYKColorspace.
  super(red, green, blue, opacity)
end

Class Method Details

.from_color(color_name) ⇒ Object

Raises:

  • (ArgumentError)


33
34
35
36
37
# File 'lib/rmagick4j/pixel.rb', line 33

def self.from_color(color_name)
  result = Magick4J::ColorDatabase.lookUp(color_name)
  raise ArgumentError, "invalid color name: #{color_name}" if result.nil?
  result
end

.from_HSL(array) ⇒ Object

Raises:

  • (ArgumentError)


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/rmagick4j/pixel.rb', line 39

def self.from_HSL(array)
  raise ArgumentError, 'array argument must have at least 3 elements' if array.size < 3
  # It can't be 'hue, saturation, lightness = array' because array length
  # can be greater than 3.
  hue, saturation, lightness = array[0], array[1], array[2]
  r, g, b = if saturation == 0
              3*[[[0, QuantumRange*lightness].max, QuantumRange].min.floor.to_i]
            else
              m2 =  if lightness <= 0.5
                      lightness*(saturation + 1.0)
                    else
                      lightness + saturation - (lightness*saturation)
                    end
              m1 = 2.0*lightness - m2
              
              [
                [[0, QuantumRange*from_hue(m1, m2, hue+1.0/3.0)].max, QuantumRange].min.floor.to_i,
                [[0, QuantumRange*from_hue(m1, m2, hue)].max, QuantumRange].min.floor.to_i,
                [[0, QuantumRange*from_hue(m1, m2, hue-1.0/3.0)].max, QuantumRange].min.floor.to_i
              ]
            end
  Pixel.new(r, g, b)
end

Instance Method Details

#<=>(pixel) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/rmagick4j/pixel.rb', line 67

def <=>(pixel)
  # Alphabetical algorithm.
  if red != pixel.red
    red <=> pixel.red
  elsif green != pixel.green
    green <=> pixel.green
  elsif blue == pixel.blue
    blue <=> pixel.blue
  elsif opacity != pixel.opacity
    opacity <=> pixel.opacity
  else
# Enebo: I added as a last test in conditional (is this needed? test?)
# Serabe: In fact, I don't know, but it is the way RMagick does it.
    self.class <=> pixel.class
  end
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/rmagick4j/pixel.rb', line 63

def eql?(other)
  (self <=> other) == 0
end

#fcmp(pixel, fuzz = 0.0, colorspace = nil) ⇒ Object

TODO: Hook colorspace into this method Extracted from color.c:1698

Raises:

  • (TypeError)


89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/rmagick4j/pixel.rb', line 89

def fcmp(pixel, fuzz=0.0, colorspace=nil)
  raise TypeError.new("wrong argument type #{pixel.class.name} (expected Data)") unless pixel.kind_of? Pixel
  raise TypeError.new("") unless fuzz.kind_of? Numeric
  if colorspace and !colorspace.kind_of? ::Magick::ColorspaceType
    raise TypeError.new("Not a colorspace") 
  end
  
  fuzz = 3.0*([fuzz.to_f, 0.7071067811865475244008443621048490].max**2)
  
  # TODO: How does matte affect this algorithm?
  
  distance = (red-pixel.red)**2
  return false if distance > fuzz
  distance += (green-pixel.green)**2
  return false if distance > fuzz
  distance += (blue-pixel.blue)**2
  return false if distance > fuzz
  true #The colors are similar!!!
end

#intensityObject

Thanks, FSM, for the RMagick documentation.



113
114
115
# File 'lib/rmagick4j/pixel.rb', line 113

def intensity
  0.299*red+0.587*green+0.114*blue
end

#to_HSLObject

Extracted from gem.c:429



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/rmagick4j/pixel.rb', line 124

def to_HSL
  r, g, b = QuantumScale*red, QuantumScale*green, QuantumScale*blue
  max = [r, g, b].max
  min = [r, g, b].min
  lightness = (min+max)/2.0
  delta = max - min
  if(delta == 0.0)
    hue, saturation = 0.0, 0.0
  else
    saturation =  if lightness <0.5
                    delta /(min+max)
                  else
                    delta / (2.0-(min+max))
                  end
    hue = if r == max
            calculate_hue(b, g, max, delta)
          elsif g == max
            (1.0/3.0) + calculate_hue(r, b, max, delta)
          elsif b == max
            (2.0/3.0)+calculate_hue(g, r, max, delta)
          end
    if hue < 0.0
      hue += 1.0
    elsif hue > 1.0
      hue -= 1.0
    end
  end
  [hue, saturation, lightness]
end

#type_check(value, conversion, typename) ⇒ Object



13
14
15
16
17
18
# File 'lib/rmagick4j/pixel.rb', line 13

def type_check(value, conversion, typename)
  unless value.respond_to? conversion
    raise TypeError.new "can't convert #{value.class.name} into #{typename}" 
  end
  value.send(conversion)
end