pxlsrt 1.6.1 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/pxlsrt +55 -55
- data/lib/pxlsrt/brute.rb +119 -119
- data/lib/pxlsrt/colors.rb +159 -159
- data/lib/pxlsrt/helpers.rb +93 -93
- data/lib/pxlsrt/lines.rb +156 -156
- data/lib/pxlsrt/smart.rb +150 -150
- data/lib/pxlsrt/version.rb +5 -5
- metadata +7 -7
data/lib/pxlsrt/colors.rb
CHANGED
@@ -1,160 +1,160 @@
|
|
1
|
-
require "oily_png"
|
2
|
-
|
3
|
-
module Pxlsrt
|
4
|
-
##
|
5
|
-
# Includes color operations.
|
6
|
-
class Colors
|
7
|
-
##
|
8
|
-
# Converts a ChunkyPNG pixel into an array of the red, green, blue, and alpha values
|
9
|
-
def self.getRGBA(pxl)
|
10
|
-
return [ChunkyPNG::Color.r(pxl), ChunkyPNG::Color.g(pxl), ChunkyPNG::Color.b(pxl), ChunkyPNG::Color.a(pxl)]
|
11
|
-
end
|
12
|
-
##
|
13
|
-
# Check if file is a PNG image. ChunkyPNG only works with PNG images. Eventually, I might use conversion tools to add support, but not right now.
|
14
|
-
def self.isPNG?(path)
|
15
|
-
return File.
|
16
|
-
end
|
17
|
-
##
|
18
|
-
# Converts an RGB-like array ([red, green, blue]) into an HSB-like array ([hue, saturation, brightness]).
|
19
|
-
def self.rgb2hsb(rgb)
|
20
|
-
r = rgb[0] / 255.0
|
21
|
-
g = rgb[1] / 255.0
|
22
|
-
b = rgb[2] / 255.0
|
23
|
-
max = [r, g, b].max
|
24
|
-
min = [r, g, b].min
|
25
|
-
delta = max - min
|
26
|
-
v = max * 100
|
27
|
-
if (max != 0.0)
|
28
|
-
s = delta / max *100
|
29
|
-
else
|
30
|
-
s = 0.0
|
31
|
-
end
|
32
|
-
if (s == 0.0)
|
33
|
-
h = 0.0
|
34
|
-
else
|
35
|
-
if (r == max)
|
36
|
-
h = (g - b) / delta
|
37
|
-
elsif (g == max)
|
38
|
-
h = 2 + (b - r) / delta
|
39
|
-
elsif (b == max)
|
40
|
-
h = 4 + (r - g) / delta
|
41
|
-
end
|
42
|
-
h *= 60.0
|
43
|
-
if (h < 0)
|
44
|
-
h += 360.0
|
45
|
-
end
|
46
|
-
end
|
47
|
-
return [h,s,v]
|
48
|
-
end
|
49
|
-
##
|
50
|
-
# Averages an array of RGB-like arrays.
|
51
|
-
def self.colorAverage(ca, chunky = false)
|
52
|
-
if ca.length==1
|
53
|
-
return ca.first
|
54
|
-
end
|
55
|
-
Pxlsrt::Helpers.verbose(ca) if ca.length == 0
|
56
|
-
if !chunky
|
57
|
-
r=((ca.collect { |c| c[0] }).inject{ |sum, el| sum+el }).to_f / ca.size
|
58
|
-
g=((ca.collect { |c| c[1] }).inject{ |sum, el| sum+el }).to_f / ca.size
|
59
|
-
b=((ca.collect { |c| c[2] }).inject{ |sum, el| sum+el }).to_f / ca.size
|
60
|
-
a=((ca.collect { |c| c[3] }).inject{ |sum, el| sum+el }).to_f / ca.size
|
61
|
-
return [r.to_i, g.to_i, b.to_i, a.to_i]
|
62
|
-
else
|
63
|
-
r=((ca.collect { |c| ChunkyPNG::Color.r(c) }).inject{ |sum, el| sum+el }).to_f / ca.size
|
64
|
-
g=((ca.collect { |c| ChunkyPNG::Color.g(c) }).inject{ |sum, el| sum+el }).to_f / ca.size
|
65
|
-
b=((ca.collect { |c| ChunkyPNG::Color.b(c) }).inject{ |sum, el| sum+el }).to_f / ca.size
|
66
|
-
a=((ca.collect { |c| ChunkyPNG::Color.a(c) }).inject{ |sum, el| sum+el }).to_f / ca.size
|
67
|
-
return ChunkyPNG::Color.rgba(r.to_i, g.to_i, b.to_i, a.to_i)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
##
|
71
|
-
# Determines color distance from each other using the Pythagorean theorem.
|
72
|
-
def self.colorDistance(c1,c2,chunky = false)
|
73
|
-
if !chunky
|
74
|
-
return Math.sqrt((c1[0]-c2[0])**2+(c1[1]-c2[1])**2+(c1[2]-c2[2])**2+(c1[3]-c2[3])**2)
|
75
|
-
else
|
76
|
-
return Math.sqrt((ChunkyPNG::Color.r(c1)-ChunkyPNG::Color.r(c2))**2+(ChunkyPNG::Color.g(c1)-ChunkyPNG::Color.g(c2))**2+(ChunkyPNG::Color.b(c1)-ChunkyPNG::Color.b(c2))**2+(ChunkyPNG::Color.a(c1)-ChunkyPNG::Color.a(c2))**2)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
##
|
80
|
-
# Uses a combination of color averaging and color distance to find how "unique" a color is.
|
81
|
-
def self.colorUniqueness(c, ca, chunky = false)
|
82
|
-
return Pxlsrt::Colors.colorDistance(c, Pxlsrt::Colors.colorAverage(ca, chunky), chunky)
|
83
|
-
end
|
84
|
-
##
|
85
|
-
# Sorts an array of colors based on a method.
|
86
|
-
# Available methods:
|
87
|
-
# * sum-rgb (default)
|
88
|
-
# * sum-rgba
|
89
|
-
# * red
|
90
|
-
# * yellow
|
91
|
-
# * green
|
92
|
-
# * cyan
|
93
|
-
# * blue
|
94
|
-
# * magenta
|
95
|
-
# * hue
|
96
|
-
# * saturation
|
97
|
-
# * brightness
|
98
|
-
# * sum-hsb
|
99
|
-
# * sum-hsba
|
100
|
-
# * uniqueness
|
101
|
-
# * luma
|
102
|
-
# * random
|
103
|
-
# * alpha
|
104
|
-
def self.pixelSort(list, how, reverse)
|
105
|
-
mhm=[]
|
106
|
-
Pxlsrt::Helpers.error(list) if list.length == 0
|
107
|
-
case how.downcase
|
108
|
-
when "sum-rgb"
|
109
|
-
mhm= list.sort_by { |c| ChunkyPNG::Color.r(c)+ChunkyPNG::Color.g(c)+ChunkyPNG::Color.b(c) }
|
110
|
-
when "sum-rgba"
|
111
|
-
mhm=list.sort_by { |c| ChunkyPNG::Color.r(c)+ChunkyPNG::Color.g(c)+ChunkyPNG::Color.b(c)+ChunkyPNG::Color.a(c) }
|
112
|
-
when "red"
|
113
|
-
mhm= list.sort_by { |c| ChunkyPNG::Color.r(c) }
|
114
|
-
when "yellow"
|
115
|
-
mhm=list.sort_by { |c| ChunkyPNG::Color.r(c)+ChunkyPNG::Color.g(c) }
|
116
|
-
when "green"
|
117
|
-
mhm= list.sort_by { |c| ChunkyPNG::Color.g(c) }
|
118
|
-
when "cyan"
|
119
|
-
mhm=list.sort_by { |c| ChunkyPNG::Color.g(c)+ChunkyPNG::Color.b(c) }
|
120
|
-
when "blue"
|
121
|
-
mhm= list.sort_by { |c| ChunkyPNG::Color.b(c) }
|
122
|
-
when "magenta"
|
123
|
-
mhm=list.sort_by { |c| ChunkyPNG::Color.r(c)+ChunkyPNG::Color.b(c) }
|
124
|
-
when "hue"
|
125
|
-
mhm= list.sort_by { |c| d = Pxlsrt::Colors.getRGBA(c); Pxlsrt::Colors.rgb2hsb(d)[0] }
|
126
|
-
when "saturation"
|
127
|
-
mhm= list.sort_by { |c| d = Pxlsrt::Colors.getRGBA(c); Pxlsrt::Colors.rgb2hsb(d)[1] }
|
128
|
-
when "brightness"
|
129
|
-
mhm= list.sort_by { |c| d = Pxlsrt::Colors.getRGBA(c); Pxlsrt::Colors.rgb2hsb(d)[2] }
|
130
|
-
when "sum-hsb"
|
131
|
-
mhm= list.sort_by { |c| d = Pxlsrt::Colors.getRGBA(c); k=Pxlsrt::Colors.rgb2hsb(d); k[0]*100.0/360+k[1]+k[2] }
|
132
|
-
when "sum-hsba"
|
133
|
-
mhm= list.sort_by { |c| d = Pxlsrt::Colors.getRGBA(c); k=Pxlsrt::Colors.rgb2hsb(d); k[0]*100.0/360+k[1]+k[2]+d.a*100.0/255 }
|
134
|
-
when "uniqueness"
|
135
|
-
avg=Pxlsrt::Colors.colorAverage(list, true)
|
136
|
-
mhm=list.sort_by { |c| Pxlsrt::Colors.colorUniqueness(c, [avg], true) }
|
137
|
-
when "luma"
|
138
|
-
mhm=list.sort_by { |c| ChunkyPNG::Color.r(c)*0.2126+ChunkyPNG::Color.g(c)*0.7152+ChunkyPNG::Color.b(c)*0.0722 }
|
139
|
-
when "random"
|
140
|
-
mhm=list.shuffle
|
141
|
-
when "alpha"
|
142
|
-
mhm=list.sort_by{ |c| ChunkyPNG::Color.a(c) }
|
143
|
-
else
|
144
|
-
mhm= list.sort_by { |c| ChunkyPNG::Color.r(c)+ChunkyPNG::Color.g(c)+ChunkyPNG::Color.b(c) }
|
145
|
-
end
|
146
|
-
if reverse == 0
|
147
|
-
return mhm
|
148
|
-
elsif reverse == 1
|
149
|
-
return mhm.reverse
|
150
|
-
else
|
151
|
-
return rand(0..1)==0 ? mhm : mhm.reverse
|
152
|
-
end
|
153
|
-
end
|
154
|
-
##
|
155
|
-
# Turns an RGB-like array into ChunkyPNG's color
|
156
|
-
def self.arrayToRGBA(a)
|
157
|
-
return ChunkyPNG::Color.rgba(a[0], a[1], a[2], a[3])
|
158
|
-
end
|
159
|
-
end
|
1
|
+
require "oily_png"
|
2
|
+
|
3
|
+
module Pxlsrt
|
4
|
+
##
|
5
|
+
# Includes color operations.
|
6
|
+
class Colors
|
7
|
+
##
|
8
|
+
# Converts a ChunkyPNG pixel into an array of the red, green, blue, and alpha values
|
9
|
+
def self.getRGBA(pxl)
|
10
|
+
return [ChunkyPNG::Color.r(pxl), ChunkyPNG::Color.g(pxl), ChunkyPNG::Color.b(pxl), ChunkyPNG::Color.a(pxl)]
|
11
|
+
end
|
12
|
+
##
|
13
|
+
# Check if file is a PNG image. ChunkyPNG only works with PNG images. Eventually, I might use conversion tools to add support, but not right now.
|
14
|
+
def self.isPNG?(path)
|
15
|
+
return File.open(path, 'rb').read(9).include?('PNG')
|
16
|
+
end
|
17
|
+
##
|
18
|
+
# Converts an RGB-like array ([red, green, blue]) into an HSB-like array ([hue, saturation, brightness]).
|
19
|
+
def self.rgb2hsb(rgb)
|
20
|
+
r = rgb[0] / 255.0
|
21
|
+
g = rgb[1] / 255.0
|
22
|
+
b = rgb[2] / 255.0
|
23
|
+
max = [r, g, b].max
|
24
|
+
min = [r, g, b].min
|
25
|
+
delta = max - min
|
26
|
+
v = max * 100
|
27
|
+
if (max != 0.0)
|
28
|
+
s = delta / max *100
|
29
|
+
else
|
30
|
+
s = 0.0
|
31
|
+
end
|
32
|
+
if (s == 0.0)
|
33
|
+
h = 0.0
|
34
|
+
else
|
35
|
+
if (r == max)
|
36
|
+
h = (g - b) / delta
|
37
|
+
elsif (g == max)
|
38
|
+
h = 2 + (b - r) / delta
|
39
|
+
elsif (b == max)
|
40
|
+
h = 4 + (r - g) / delta
|
41
|
+
end
|
42
|
+
h *= 60.0
|
43
|
+
if (h < 0)
|
44
|
+
h += 360.0
|
45
|
+
end
|
46
|
+
end
|
47
|
+
return [h,s,v]
|
48
|
+
end
|
49
|
+
##
|
50
|
+
# Averages an array of RGB-like arrays.
|
51
|
+
def self.colorAverage(ca, chunky = false)
|
52
|
+
if ca.length==1
|
53
|
+
return ca.first
|
54
|
+
end
|
55
|
+
Pxlsrt::Helpers.verbose(ca) if ca.length == 0
|
56
|
+
if !chunky
|
57
|
+
r=((ca.collect { |c| c[0] }).inject{ |sum, el| sum+el }).to_f / ca.size
|
58
|
+
g=((ca.collect { |c| c[1] }).inject{ |sum, el| sum+el }).to_f / ca.size
|
59
|
+
b=((ca.collect { |c| c[2] }).inject{ |sum, el| sum+el }).to_f / ca.size
|
60
|
+
a=((ca.collect { |c| c[3] }).inject{ |sum, el| sum+el }).to_f / ca.size
|
61
|
+
return [r.to_i, g.to_i, b.to_i, a.to_i]
|
62
|
+
else
|
63
|
+
r=((ca.collect { |c| ChunkyPNG::Color.r(c) }).inject{ |sum, el| sum+el }).to_f / ca.size
|
64
|
+
g=((ca.collect { |c| ChunkyPNG::Color.g(c) }).inject{ |sum, el| sum+el }).to_f / ca.size
|
65
|
+
b=((ca.collect { |c| ChunkyPNG::Color.b(c) }).inject{ |sum, el| sum+el }).to_f / ca.size
|
66
|
+
a=((ca.collect { |c| ChunkyPNG::Color.a(c) }).inject{ |sum, el| sum+el }).to_f / ca.size
|
67
|
+
return ChunkyPNG::Color.rgba(r.to_i, g.to_i, b.to_i, a.to_i)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
##
|
71
|
+
# Determines color distance from each other using the Pythagorean theorem.
|
72
|
+
def self.colorDistance(c1,c2,chunky = false)
|
73
|
+
if !chunky
|
74
|
+
return Math.sqrt((c1[0]-c2[0])**2+(c1[1]-c2[1])**2+(c1[2]-c2[2])**2+(c1[3]-c2[3])**2)
|
75
|
+
else
|
76
|
+
return Math.sqrt((ChunkyPNG::Color.r(c1)-ChunkyPNG::Color.r(c2))**2+(ChunkyPNG::Color.g(c1)-ChunkyPNG::Color.g(c2))**2+(ChunkyPNG::Color.b(c1)-ChunkyPNG::Color.b(c2))**2+(ChunkyPNG::Color.a(c1)-ChunkyPNG::Color.a(c2))**2)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
##
|
80
|
+
# Uses a combination of color averaging and color distance to find how "unique" a color is.
|
81
|
+
def self.colorUniqueness(c, ca, chunky = false)
|
82
|
+
return Pxlsrt::Colors.colorDistance(c, Pxlsrt::Colors.colorAverage(ca, chunky), chunky)
|
83
|
+
end
|
84
|
+
##
|
85
|
+
# Sorts an array of colors based on a method.
|
86
|
+
# Available methods:
|
87
|
+
# * sum-rgb (default)
|
88
|
+
# * sum-rgba
|
89
|
+
# * red
|
90
|
+
# * yellow
|
91
|
+
# * green
|
92
|
+
# * cyan
|
93
|
+
# * blue
|
94
|
+
# * magenta
|
95
|
+
# * hue
|
96
|
+
# * saturation
|
97
|
+
# * brightness
|
98
|
+
# * sum-hsb
|
99
|
+
# * sum-hsba
|
100
|
+
# * uniqueness
|
101
|
+
# * luma
|
102
|
+
# * random
|
103
|
+
# * alpha
|
104
|
+
def self.pixelSort(list, how, reverse)
|
105
|
+
mhm=[]
|
106
|
+
Pxlsrt::Helpers.error(list) if list.length == 0
|
107
|
+
case how.downcase
|
108
|
+
when "sum-rgb"
|
109
|
+
mhm= list.sort_by { |c| ChunkyPNG::Color.r(c)+ChunkyPNG::Color.g(c)+ChunkyPNG::Color.b(c) }
|
110
|
+
when "sum-rgba"
|
111
|
+
mhm=list.sort_by { |c| ChunkyPNG::Color.r(c)+ChunkyPNG::Color.g(c)+ChunkyPNG::Color.b(c)+ChunkyPNG::Color.a(c) }
|
112
|
+
when "red"
|
113
|
+
mhm= list.sort_by { |c| ChunkyPNG::Color.r(c) }
|
114
|
+
when "yellow"
|
115
|
+
mhm=list.sort_by { |c| ChunkyPNG::Color.r(c)+ChunkyPNG::Color.g(c) }
|
116
|
+
when "green"
|
117
|
+
mhm= list.sort_by { |c| ChunkyPNG::Color.g(c) }
|
118
|
+
when "cyan"
|
119
|
+
mhm=list.sort_by { |c| ChunkyPNG::Color.g(c)+ChunkyPNG::Color.b(c) }
|
120
|
+
when "blue"
|
121
|
+
mhm= list.sort_by { |c| ChunkyPNG::Color.b(c) }
|
122
|
+
when "magenta"
|
123
|
+
mhm=list.sort_by { |c| ChunkyPNG::Color.r(c)+ChunkyPNG::Color.b(c) }
|
124
|
+
when "hue"
|
125
|
+
mhm= list.sort_by { |c| d = Pxlsrt::Colors.getRGBA(c); Pxlsrt::Colors.rgb2hsb(d)[0] }
|
126
|
+
when "saturation"
|
127
|
+
mhm= list.sort_by { |c| d = Pxlsrt::Colors.getRGBA(c); Pxlsrt::Colors.rgb2hsb(d)[1] }
|
128
|
+
when "brightness"
|
129
|
+
mhm= list.sort_by { |c| d = Pxlsrt::Colors.getRGBA(c); Pxlsrt::Colors.rgb2hsb(d)[2] }
|
130
|
+
when "sum-hsb"
|
131
|
+
mhm= list.sort_by { |c| d = Pxlsrt::Colors.getRGBA(c); k=Pxlsrt::Colors.rgb2hsb(d); k[0]*100.0/360+k[1]+k[2] }
|
132
|
+
when "sum-hsba"
|
133
|
+
mhm= list.sort_by { |c| d = Pxlsrt::Colors.getRGBA(c); k=Pxlsrt::Colors.rgb2hsb(d); k[0]*100.0/360+k[1]+k[2]+d.a*100.0/255 }
|
134
|
+
when "uniqueness"
|
135
|
+
avg=Pxlsrt::Colors.colorAverage(list, true)
|
136
|
+
mhm=list.sort_by { |c| Pxlsrt::Colors.colorUniqueness(c, [avg], true) }
|
137
|
+
when "luma"
|
138
|
+
mhm=list.sort_by { |c| ChunkyPNG::Color.r(c)*0.2126+ChunkyPNG::Color.g(c)*0.7152+ChunkyPNG::Color.b(c)*0.0722 }
|
139
|
+
when "random"
|
140
|
+
mhm=list.shuffle
|
141
|
+
when "alpha"
|
142
|
+
mhm=list.sort_by{ |c| ChunkyPNG::Color.a(c) }
|
143
|
+
else
|
144
|
+
mhm= list.sort_by { |c| ChunkyPNG::Color.r(c)+ChunkyPNG::Color.g(c)+ChunkyPNG::Color.b(c) }
|
145
|
+
end
|
146
|
+
if reverse == 0
|
147
|
+
return mhm
|
148
|
+
elsif reverse == 1
|
149
|
+
return mhm.reverse
|
150
|
+
else
|
151
|
+
return rand(0..1)==0 ? mhm : mhm.reverse
|
152
|
+
end
|
153
|
+
end
|
154
|
+
##
|
155
|
+
# Turns an RGB-like array into ChunkyPNG's color
|
156
|
+
def self.arrayToRGBA(a)
|
157
|
+
return ChunkyPNG::Color.rgba(a[0], a[1], a[2], a[3])
|
158
|
+
end
|
159
|
+
end
|
160
160
|
end
|
data/lib/pxlsrt/helpers.rb
CHANGED
@@ -1,94 +1,94 @@
|
|
1
|
-
module Pxlsrt
|
2
|
-
##
|
3
|
-
# Methods not having to do with image or color manipulation.
|
4
|
-
class Helpers
|
5
|
-
##
|
6
|
-
# Determines if a value has content.
|
7
|
-
def self.contented(c)
|
8
|
-
return
|
9
|
-
end
|
10
|
-
##
|
11
|
-
# Used to output a red string to the terminal.
|
12
|
-
def self.red(what)
|
13
|
-
return "\e[31m#{what}\e[0m"
|
14
|
-
end
|
15
|
-
##
|
16
|
-
# Used to output a cyan string to the terminal.
|
17
|
-
def self.cyan(what)
|
18
|
-
return "\e[36m#{what}\e[0m"
|
19
|
-
end
|
20
|
-
##
|
21
|
-
# Determines if a string can be a float or integer.
|
22
|
-
def self.isNumeric?(s)
|
23
|
-
true if Float(s) rescue false
|
24
|
-
end
|
25
|
-
##
|
26
|
-
# Checks if supplied options follow the rules.
|
27
|
-
def self.checkOptions(options, rules)
|
28
|
-
match=true
|
29
|
-
for o in options.keys
|
30
|
-
o_match=false
|
31
|
-
if rules[o].class==Array
|
32
|
-
if rules[o].include?(options[o])
|
33
|
-
o_match=true
|
34
|
-
else
|
35
|
-
for r in 0...rules[o].length
|
36
|
-
if rules[o][r].class==Hash
|
37
|
-
for n in rules[o][r][:class]
|
38
|
-
if n==options[o].class
|
39
|
-
o_match=match
|
40
|
-
break
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
if o_match==true
|
45
|
-
break
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
elsif rules[o] == :anything
|
50
|
-
o_match = true
|
51
|
-
end
|
52
|
-
match=(match and o_match)
|
53
|
-
if match==false
|
54
|
-
break
|
55
|
-
end
|
56
|
-
end
|
57
|
-
return match
|
58
|
-
end
|
59
|
-
##
|
60
|
-
# Pixel sorting helper to eliminate repetition.
|
61
|
-
def self.handlePixelSort(band, o)
|
62
|
-
if (o[:reverse].class == String and (o[:reverse].downcase == "reverse" or o[:reverse] == "")) or o[:reverse] == true
|
63
|
-
reverse = 1
|
64
|
-
elsif o[:reverse].class == String and o[:reverse].downcase == "either"
|
65
|
-
reverse = -1
|
66
|
-
else
|
67
|
-
reverse = 0
|
68
|
-
end
|
69
|
-
if o[:smooth]
|
70
|
-
u = band.group_by { |x| x }
|
71
|
-
k = u.keys
|
72
|
-
else
|
73
|
-
k = band
|
74
|
-
end
|
75
|
-
sortedBand = Pxlsrt::Colors.pixelSort(
|
76
|
-
k,
|
77
|
-
o[:method],
|
78
|
-
reverse
|
79
|
-
)
|
80
|
-
sortedBand = sortedBand.map { |x| u[x] }.flatten(1) if o[:smooth]
|
81
|
-
return Pxlsrt::Lines.handleMiddlate(sortedBand, o[:middle])
|
82
|
-
end
|
83
|
-
##
|
84
|
-
# Prints an error message.
|
85
|
-
def self.error(what)
|
86
|
-
puts "#{Pxlsrt::Helpers.red("pxlsrt")} #{what}"
|
87
|
-
end
|
88
|
-
##
|
89
|
-
# Prints something.
|
90
|
-
def self.verbose(what)
|
91
|
-
puts "#{Pxlsrt::Helpers.cyan("pxlsrt")} #{what}"
|
92
|
-
end
|
93
|
-
end
|
1
|
+
module Pxlsrt
|
2
|
+
##
|
3
|
+
# Methods not having to do with image or color manipulation.
|
4
|
+
class Helpers
|
5
|
+
##
|
6
|
+
# Determines if a value has content.
|
7
|
+
def self.contented(c)
|
8
|
+
return c != nil
|
9
|
+
end
|
10
|
+
##
|
11
|
+
# Used to output a red string to the terminal.
|
12
|
+
def self.red(what)
|
13
|
+
return "\e[31m#{what}\e[0m"
|
14
|
+
end
|
15
|
+
##
|
16
|
+
# Used to output a cyan string to the terminal.
|
17
|
+
def self.cyan(what)
|
18
|
+
return "\e[36m#{what}\e[0m"
|
19
|
+
end
|
20
|
+
##
|
21
|
+
# Determines if a string can be a float or integer.
|
22
|
+
def self.isNumeric?(s)
|
23
|
+
true if Float(s) rescue false
|
24
|
+
end
|
25
|
+
##
|
26
|
+
# Checks if supplied options follow the rules.
|
27
|
+
def self.checkOptions(options, rules)
|
28
|
+
match=true
|
29
|
+
for o in options.keys
|
30
|
+
o_match=false
|
31
|
+
if rules[o].class==Array
|
32
|
+
if rules[o].include?(options[o])
|
33
|
+
o_match=true
|
34
|
+
else
|
35
|
+
for r in 0...rules[o].length
|
36
|
+
if rules[o][r].class==Hash
|
37
|
+
for n in rules[o][r][:class]
|
38
|
+
if n==options[o].class
|
39
|
+
o_match=match
|
40
|
+
break
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
if o_match==true
|
45
|
+
break
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
elsif rules[o] == :anything
|
50
|
+
o_match = true
|
51
|
+
end
|
52
|
+
match=(match and o_match)
|
53
|
+
if match==false
|
54
|
+
break
|
55
|
+
end
|
56
|
+
end
|
57
|
+
return match
|
58
|
+
end
|
59
|
+
##
|
60
|
+
# Pixel sorting helper to eliminate repetition.
|
61
|
+
def self.handlePixelSort(band, o)
|
62
|
+
if (o[:reverse].class == String and (o[:reverse].downcase == "reverse" or o[:reverse] == "")) or o[:reverse] == true
|
63
|
+
reverse = 1
|
64
|
+
elsif o[:reverse].class == String and o[:reverse].downcase == "either"
|
65
|
+
reverse = -1
|
66
|
+
else
|
67
|
+
reverse = 0
|
68
|
+
end
|
69
|
+
if o[:smooth]
|
70
|
+
u = band.group_by { |x| x }
|
71
|
+
k = u.keys
|
72
|
+
else
|
73
|
+
k = band
|
74
|
+
end
|
75
|
+
sortedBand = Pxlsrt::Colors.pixelSort(
|
76
|
+
k,
|
77
|
+
o[:method],
|
78
|
+
reverse
|
79
|
+
)
|
80
|
+
sortedBand = sortedBand.map { |x| u[x] }.flatten(1) if o[:smooth]
|
81
|
+
return Pxlsrt::Lines.handleMiddlate(sortedBand, o[:middle])
|
82
|
+
end
|
83
|
+
##
|
84
|
+
# Prints an error message.
|
85
|
+
def self.error(what)
|
86
|
+
puts "#{Pxlsrt::Helpers.red("pxlsrt")} #{what}"
|
87
|
+
end
|
88
|
+
##
|
89
|
+
# Prints something.
|
90
|
+
def self.verbose(what)
|
91
|
+
puts "#{Pxlsrt::Helpers.cyan("pxlsrt")} #{what}"
|
92
|
+
end
|
93
|
+
end
|
94
94
|
end
|