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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d8dde41dd5c41e17cc78c762f2ff4078b49ea74
|
4
|
+
data.tar.gz: c61a4474522cb49ef19a38b8fbf14f23021947c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17bf3a4c5c6d18fe8861c703b2f0e388d3c76156e353a8a2e801d2bd9a384b342c97998ef4df32b16733760734c88d50d911985d48250721e595f8e47ed12bfc
|
7
|
+
data.tar.gz: 49d453ad7ca2842aeefeaa4236e0b4830399f1da58b234f65265209caf4516087d6bcbddad3544632d1da32fbbb383336f2cd59c81e6e88776847962246c0582
|
data/bin/pxlsrt
CHANGED
@@ -1,56 +1,56 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'pxlsrt'
|
5
|
-
require 'thor'
|
6
|
-
|
7
|
-
##
|
8
|
-
# The command line. Created using Thor. Universal options:
|
9
|
-
# * reverse - Reverses the bands or randomly reverses or doesn't reverse.
|
10
|
-
# * vertical - Sorts vertically.
|
11
|
-
# * diagonal - Sorts diagonally. Use with vertical to change the diagonals' orientation.
|
12
|
-
# * smooth - "Smoothes" sorted values by grouping identical pixels together.
|
13
|
-
# * method - What method to use to sort pixels.
|
14
|
-
# * verbose - Have pxlsrt tell you what it's working on.
|
15
|
-
# * help - More in depth commands.
|
16
|
-
class CLI < Thor
|
17
|
-
class_option :reverse, :default => false, :aliases => "-r"
|
18
|
-
class_option :vertical, :type => :boolean, :default => false, :aliases => "-v"
|
19
|
-
class_option :diagonal, :type => :boolean, :default => false, :aliases => "-d"
|
20
|
-
class_option :smooth, :type => :boolean, :default => false, :aliases => "-s"
|
21
|
-
class_option :method, :type => :string, :default => "sum-rgb", :banner => "[sum-rgb | red | green | blue | sum-hsb | hue | saturation | brightness | uniqueness | luma | random | cyan | magenta | yellow | alpha | sum-rgba | sum-hsba]", :aliases => "-m", :enum => ["sum-rgb", "red", "green", "blue", "sum-hsb", "hue", "saturation", "brightness", "uniqueness", "luma", "random", "cyan", "magenta", "yellow", "alpha", "sum-rgba", "sum-hsba"]
|
22
|
-
class_option :verbose, :type => :boolean, :default => false, :aliases => "-V"
|
23
|
-
class_option :middle, :default => false, :aliases => "-M"
|
24
|
-
|
25
|
-
option :min, :type => :numeric, :default => Float::INFINITY, :banner => "MINIMUM BANDWIDTH"
|
26
|
-
option :max, :type => :numeric, :default => Float::INFINITY, :banner => "MAXIMUM BANDWIDTH"
|
27
|
-
desc "brute INPUT OUTPUT [options]", "Brute pixel sorting"
|
28
|
-
##
|
29
|
-
# Specific options:
|
30
|
-
# * min - Minimum bandwidth.
|
31
|
-
# * max - Maximum bandwidth.
|
32
|
-
def brute(input, output)
|
33
|
-
k={:trusted=>true}
|
34
|
-
for o in options.keys
|
35
|
-
k[o.to_sym]=options[o]
|
36
|
-
end
|
37
|
-
Pxlsrt::Brute.suite(input, output, k)
|
38
|
-
end
|
39
|
-
|
40
|
-
option :absolute, :type => :boolean, :default => false, :aliases => "-a", :banner => "ABSOLUTE EDGE FINDING"
|
41
|
-
option :threshold, :type => :numeric, :default => 20, :aliases => "-t"
|
42
|
-
desc "smart INPUT OUTPUT [options]", "Smart pixel sorting"
|
43
|
-
##
|
44
|
-
# Specific options:
|
45
|
-
# * threshold - Number used in edge finding. Specifics explained under "absolute".
|
46
|
-
# * absolute - Make edge finding absolute over relative. For example, define a range as a collection of values under the threshold. Relative edge finding is when the contrast of the next pixel is larger than the threshold.
|
47
|
-
def smart(input, output)
|
48
|
-
k={:trusted=>true}
|
49
|
-
for o in options.keys
|
50
|
-
k[o.to_sym]=options[o]
|
51
|
-
end
|
52
|
-
Pxlsrt::Smart.suite(input, output, k)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'pxlsrt'
|
5
|
+
require 'thor'
|
6
|
+
|
7
|
+
##
|
8
|
+
# The command line. Created using Thor. Universal options:
|
9
|
+
# * reverse - Reverses the bands or randomly reverses or doesn't reverse.
|
10
|
+
# * vertical - Sorts vertically.
|
11
|
+
# * diagonal - Sorts diagonally. Use with vertical to change the diagonals' orientation.
|
12
|
+
# * smooth - "Smoothes" sorted values by grouping identical pixels together.
|
13
|
+
# * method - What method to use to sort pixels.
|
14
|
+
# * verbose - Have pxlsrt tell you what it's working on.
|
15
|
+
# * help - More in depth commands.
|
16
|
+
class CLI < Thor
|
17
|
+
class_option :reverse, :default => false, :aliases => "-r"
|
18
|
+
class_option :vertical, :type => :boolean, :default => false, :aliases => "-v"
|
19
|
+
class_option :diagonal, :type => :boolean, :default => false, :aliases => "-d"
|
20
|
+
class_option :smooth, :type => :boolean, :default => false, :aliases => "-s"
|
21
|
+
class_option :method, :type => :string, :default => "sum-rgb", :banner => "[sum-rgb | red | green | blue | sum-hsb | hue | saturation | brightness | uniqueness | luma | random | cyan | magenta | yellow | alpha | sum-rgba | sum-hsba]", :aliases => "-m", :enum => ["sum-rgb", "red", "green", "blue", "sum-hsb", "hue", "saturation", "brightness", "uniqueness", "luma", "random", "cyan", "magenta", "yellow", "alpha", "sum-rgba", "sum-hsba"]
|
22
|
+
class_option :verbose, :type => :boolean, :default => false, :aliases => "-V"
|
23
|
+
class_option :middle, :default => false, :aliases => "-M"
|
24
|
+
|
25
|
+
option :min, :type => :numeric, :default => Float::INFINITY, :banner => "MINIMUM BANDWIDTH"
|
26
|
+
option :max, :type => :numeric, :default => Float::INFINITY, :banner => "MAXIMUM BANDWIDTH"
|
27
|
+
desc "brute INPUT OUTPUT [options]", "Brute pixel sorting"
|
28
|
+
##
|
29
|
+
# Specific options:
|
30
|
+
# * min - Minimum bandwidth.
|
31
|
+
# * max - Maximum bandwidth.
|
32
|
+
def brute(input, output)
|
33
|
+
k={:trusted=>true}
|
34
|
+
for o in options.keys
|
35
|
+
k[o.to_sym]=options[o]
|
36
|
+
end
|
37
|
+
Pxlsrt::Brute.suite(input, output, k)
|
38
|
+
end
|
39
|
+
|
40
|
+
option :absolute, :type => :boolean, :default => false, :aliases => "-a", :banner => "ABSOLUTE EDGE FINDING"
|
41
|
+
option :threshold, :type => :numeric, :default => 20, :aliases => "-t"
|
42
|
+
desc "smart INPUT OUTPUT [options]", "Smart pixel sorting"
|
43
|
+
##
|
44
|
+
# Specific options:
|
45
|
+
# * threshold - Number used in edge finding. Specifics explained under "absolute".
|
46
|
+
# * absolute - Make edge finding absolute over relative. For example, define a range as a collection of values under the threshold. Relative edge finding is when the contrast of the next pixel is larger than the threshold.
|
47
|
+
def smart(input, output)
|
48
|
+
k={:trusted=>true}
|
49
|
+
for o in options.keys
|
50
|
+
k[o.to_sym]=options[o]
|
51
|
+
end
|
52
|
+
Pxlsrt::Smart.suite(input, output, k)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
56
|
CLI.start(ARGV)
|
data/lib/pxlsrt/brute.rb
CHANGED
@@ -1,120 +1,120 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'oily_png'
|
3
|
-
|
4
|
-
module Pxlsrt
|
5
|
-
##
|
6
|
-
# Brute sorting creates bands for sorting using a range to determine the bandwidths,
|
7
|
-
# as opposed to smart sorting which uses edge-finding to create bands.
|
8
|
-
class Brute
|
9
|
-
##
|
10
|
-
# Uses Pxlsrt::Brute.brute to input and output from one method.
|
11
|
-
def self.suite(inputFileName, outputFileName, o={})
|
12
|
-
kml=Pxlsrt::Brute.brute(inputFileName, o)
|
13
|
-
if Pxlsrt::Helpers.contented(kml)
|
14
|
-
kml.save(outputFileName)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
##
|
18
|
-
# The main attraction of the Brute class. Returns a ChunkyPNG::Image that is sorted according to the options provided. Will return nil if it encounters an errors.
|
19
|
-
def self.brute(input, o={})
|
20
|
-
startTime=Time.now
|
21
|
-
defOptions={
|
22
|
-
:reverse => false,
|
23
|
-
:vertical => false,
|
24
|
-
:diagonal => false,
|
25
|
-
:smooth => false,
|
26
|
-
:method => "sum-rgb",
|
27
|
-
:verbose => false,
|
28
|
-
:min => Float::INFINITY,
|
29
|
-
:max => Float::INFINITY,
|
30
|
-
:trusted => false,
|
31
|
-
:middle => false
|
32
|
-
}
|
33
|
-
defRules={
|
34
|
-
:reverse => :anything,
|
35
|
-
:vertical => [false, true],
|
36
|
-
:diagonal => [false, true],
|
37
|
-
:smooth => [false, true],
|
38
|
-
:method => ["sum-rgb", "red", "green", "blue", "sum-hsb", "hue", "saturation", "brightness", "uniqueness", "luma", "random", "cyan", "magenta", "yellow", "alpha", "sum-rgba", "sum-hsba"],
|
39
|
-
:verbose => [false, true],
|
40
|
-
:min => [Float::INFINITY, {:class => [Fixnum]}],
|
41
|
-
:max => [Float::INFINITY, {:class => [Fixnum]}],
|
42
|
-
:trusted => [false, true],
|
43
|
-
:middle => :anything
|
44
|
-
}
|
45
|
-
options=defOptions.merge(o)
|
46
|
-
if o.length==0 or options[:trusted]==true or (options[:trusted]==false and o.length!=0 and Pxlsrt::Helpers.checkOptions(options, defRules)!=false)
|
47
|
-
Pxlsrt::Helpers.verbose("Options are all good.") if options[:verbose]
|
48
|
-
if input.class==String
|
49
|
-
Pxlsrt::Helpers.verbose("Getting image from file...") if options[:verbose]
|
50
|
-
if File.file?(input)
|
51
|
-
if Pxlsrt::Colors.isPNG?(input)
|
52
|
-
input=ChunkyPNG::Image.from_file(input)
|
53
|
-
else
|
54
|
-
Pxlsrt::Helpers.error("File #{input} is not a valid PNG.") if options[:verbose]
|
55
|
-
return
|
56
|
-
end
|
57
|
-
else
|
58
|
-
Pxlsrt::Helpers.error("File #{input} doesn't exist!") if options[:verbose]
|
59
|
-
return
|
60
|
-
end
|
61
|
-
elsif input.class!=String and input.class!=ChunkyPNG::Image
|
62
|
-
Pxlsrt::Helpers.error("Input is not a filename or ChunkyPNG::Image") if options[:verbose]
|
63
|
-
return
|
64
|
-
end
|
65
|
-
Pxlsrt::Helpers.verbose("Brute mode.") if options[:verbose]
|
66
|
-
Pxlsrt::Helpers.verbose("Creating Pxlsrt::Image object") if options[:verbose]
|
67
|
-
png=Pxlsrt::Image.new(input)
|
68
|
-
if !options[:vertical] and !options[:diagonal]
|
69
|
-
Pxlsrt::Helpers.verbose("Retrieving rows") if options[:verbose]
|
70
|
-
lines = png.horizontalLines
|
71
|
-
elsif options[:vertical] and !options[:diagonal]
|
72
|
-
Pxlsrt::Helpers.verbose("Retrieving columns") if options[:verbose]
|
73
|
-
lines = png.verticalLines
|
74
|
-
elsif !options[:vertical] and options[:diagonal]
|
75
|
-
Pxlsrt::Helpers.verbose("Retrieving diagonals") if options[:verbose]
|
76
|
-
lines = png.diagonalLines
|
77
|
-
elsif options[:vertical] and options[:diagonal]
|
78
|
-
Pxlsrt::Helpers.verbose("Retrieving diagonals") if options[:verbose]
|
79
|
-
lines = png.rDiagonalLines
|
80
|
-
end
|
81
|
-
if !options[:diagonal]
|
82
|
-
iterator = 0...(lines.length)
|
83
|
-
else
|
84
|
-
iterator = lines.keys
|
85
|
-
end
|
86
|
-
Pxlsrt::Helpers.verbose("Dividing and pixel sorting lines") if options[:verbose]
|
87
|
-
for k in iterator
|
88
|
-
line = lines[k]
|
89
|
-
divisions = Pxlsrt::Lines.randomSlices(line.length,options[:min],options[:max])
|
90
|
-
newLine = []
|
91
|
-
for division in divisions
|
92
|
-
band = line[division[0]..division[1]]
|
93
|
-
newLine.concat(Pxlsrt::Helpers.handlePixelSort(band, options))
|
94
|
-
end
|
95
|
-
if !options[:diagonal]
|
96
|
-
png.replaceHorizontal(k, newLine) if !options[:vertical]
|
97
|
-
png.replaceVertical(k, newLine) if options[:vertical]
|
98
|
-
else
|
99
|
-
png.replaceDiagonal(k, newLine) if !options[:vertical]
|
100
|
-
png.replaceRDiagonal(k, newLine) if options[:vertical]
|
101
|
-
end
|
102
|
-
end
|
103
|
-
endTime=Time.now
|
104
|
-
timeElapsed=endTime-startTime
|
105
|
-
if timeElapsed < 60
|
106
|
-
Pxlsrt::Helpers.verbose("Took #{timeElapsed.round(4)} second#{ timeElapsed!=1.0 ? "s" : "" }.") if options[:verbose]
|
107
|
-
else
|
108
|
-
minutes=(timeElapsed/60).floor
|
109
|
-
seconds=(timeElapsed % 60).round(4)
|
110
|
-
Pxlsrt::Helpers.verbose("Took #{minutes} minute#{ minutes!=1 ? "s" : "" } and #{seconds} second#{ seconds!=1.0 ? "s" : "" }.") if options[:verbose]
|
111
|
-
end
|
112
|
-
Pxlsrt::Helpers.verbose("Returning ChunkyPNG::Image...") if options[:verbose]
|
113
|
-
return png.returnModified
|
114
|
-
else
|
115
|
-
Pxlsrt::Helpers.error("Options specified do not follow the correct format.") if options[:verbose]
|
116
|
-
return
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
1
|
+
require 'rubygems'
|
2
|
+
require 'oily_png'
|
3
|
+
|
4
|
+
module Pxlsrt
|
5
|
+
##
|
6
|
+
# Brute sorting creates bands for sorting using a range to determine the bandwidths,
|
7
|
+
# as opposed to smart sorting which uses edge-finding to create bands.
|
8
|
+
class Brute
|
9
|
+
##
|
10
|
+
# Uses Pxlsrt::Brute.brute to input and output from one method.
|
11
|
+
def self.suite(inputFileName, outputFileName, o={})
|
12
|
+
kml=Pxlsrt::Brute.brute(inputFileName, o)
|
13
|
+
if Pxlsrt::Helpers.contented(kml)
|
14
|
+
kml.save(outputFileName)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
##
|
18
|
+
# The main attraction of the Brute class. Returns a ChunkyPNG::Image that is sorted according to the options provided. Will return nil if it encounters an errors.
|
19
|
+
def self.brute(input, o={})
|
20
|
+
startTime=Time.now
|
21
|
+
defOptions={
|
22
|
+
:reverse => false,
|
23
|
+
:vertical => false,
|
24
|
+
:diagonal => false,
|
25
|
+
:smooth => false,
|
26
|
+
:method => "sum-rgb",
|
27
|
+
:verbose => false,
|
28
|
+
:min => Float::INFINITY,
|
29
|
+
:max => Float::INFINITY,
|
30
|
+
:trusted => false,
|
31
|
+
:middle => false
|
32
|
+
}
|
33
|
+
defRules={
|
34
|
+
:reverse => :anything,
|
35
|
+
:vertical => [false, true],
|
36
|
+
:diagonal => [false, true],
|
37
|
+
:smooth => [false, true],
|
38
|
+
:method => ["sum-rgb", "red", "green", "blue", "sum-hsb", "hue", "saturation", "brightness", "uniqueness", "luma", "random", "cyan", "magenta", "yellow", "alpha", "sum-rgba", "sum-hsba"],
|
39
|
+
:verbose => [false, true],
|
40
|
+
:min => [Float::INFINITY, {:class => [Fixnum]}],
|
41
|
+
:max => [Float::INFINITY, {:class => [Fixnum]}],
|
42
|
+
:trusted => [false, true],
|
43
|
+
:middle => :anything
|
44
|
+
}
|
45
|
+
options=defOptions.merge(o)
|
46
|
+
if o.length==0 or options[:trusted]==true or (options[:trusted]==false and o.length!=0 and Pxlsrt::Helpers.checkOptions(options, defRules)!=false)
|
47
|
+
Pxlsrt::Helpers.verbose("Options are all good.") if options[:verbose]
|
48
|
+
if input.class==String
|
49
|
+
Pxlsrt::Helpers.verbose("Getting image from file...") if options[:verbose]
|
50
|
+
if File.file?(input)
|
51
|
+
if Pxlsrt::Colors.isPNG?(input)
|
52
|
+
input=ChunkyPNG::Image.from_file(input)
|
53
|
+
else
|
54
|
+
Pxlsrt::Helpers.error("File #{input} is not a valid PNG.") if options[:verbose]
|
55
|
+
return
|
56
|
+
end
|
57
|
+
else
|
58
|
+
Pxlsrt::Helpers.error("File #{input} doesn't exist!") if options[:verbose]
|
59
|
+
return
|
60
|
+
end
|
61
|
+
elsif input.class!=String and input.class!=ChunkyPNG::Image
|
62
|
+
Pxlsrt::Helpers.error("Input is not a filename or ChunkyPNG::Image") if options[:verbose]
|
63
|
+
return
|
64
|
+
end
|
65
|
+
Pxlsrt::Helpers.verbose("Brute mode.") if options[:verbose]
|
66
|
+
Pxlsrt::Helpers.verbose("Creating Pxlsrt::Image object") if options[:verbose]
|
67
|
+
png=Pxlsrt::Image.new(input)
|
68
|
+
if !options[:vertical] and !options[:diagonal]
|
69
|
+
Pxlsrt::Helpers.verbose("Retrieving rows") if options[:verbose]
|
70
|
+
lines = png.horizontalLines
|
71
|
+
elsif options[:vertical] and !options[:diagonal]
|
72
|
+
Pxlsrt::Helpers.verbose("Retrieving columns") if options[:verbose]
|
73
|
+
lines = png.verticalLines
|
74
|
+
elsif !options[:vertical] and options[:diagonal]
|
75
|
+
Pxlsrt::Helpers.verbose("Retrieving diagonals") if options[:verbose]
|
76
|
+
lines = png.diagonalLines
|
77
|
+
elsif options[:vertical] and options[:diagonal]
|
78
|
+
Pxlsrt::Helpers.verbose("Retrieving diagonals") if options[:verbose]
|
79
|
+
lines = png.rDiagonalLines
|
80
|
+
end
|
81
|
+
if !options[:diagonal]
|
82
|
+
iterator = 0...(lines.length)
|
83
|
+
else
|
84
|
+
iterator = lines.keys
|
85
|
+
end
|
86
|
+
Pxlsrt::Helpers.verbose("Dividing and pixel sorting lines") if options[:verbose]
|
87
|
+
for k in iterator
|
88
|
+
line = lines[k]
|
89
|
+
divisions = Pxlsrt::Lines.randomSlices(line.length,options[:min],options[:max])
|
90
|
+
newLine = []
|
91
|
+
for division in divisions
|
92
|
+
band = line[division[0]..division[1]]
|
93
|
+
newLine.concat(Pxlsrt::Helpers.handlePixelSort(band, options))
|
94
|
+
end
|
95
|
+
if !options[:diagonal]
|
96
|
+
png.replaceHorizontal(k, newLine) if !options[:vertical]
|
97
|
+
png.replaceVertical(k, newLine) if options[:vertical]
|
98
|
+
else
|
99
|
+
png.replaceDiagonal(k, newLine) if !options[:vertical]
|
100
|
+
png.replaceRDiagonal(k, newLine) if options[:vertical]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
endTime=Time.now
|
104
|
+
timeElapsed=endTime-startTime
|
105
|
+
if timeElapsed < 60
|
106
|
+
Pxlsrt::Helpers.verbose("Took #{timeElapsed.round(4)} second#{ timeElapsed!=1.0 ? "s" : "" }.") if options[:verbose]
|
107
|
+
else
|
108
|
+
minutes=(timeElapsed/60).floor
|
109
|
+
seconds=(timeElapsed % 60).round(4)
|
110
|
+
Pxlsrt::Helpers.verbose("Took #{minutes} minute#{ minutes!=1 ? "s" : "" } and #{seconds} second#{ seconds!=1.0 ? "s" : "" }.") if options[:verbose]
|
111
|
+
end
|
112
|
+
Pxlsrt::Helpers.verbose("Returning ChunkyPNG::Image...") if options[:verbose]
|
113
|
+
return png.returnModified
|
114
|
+
else
|
115
|
+
Pxlsrt::Helpers.error("Options specified do not follow the correct format.") if options[:verbose]
|
116
|
+
return
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
120
|
end
|