pxlsrt 1.0.0 → 1.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2c2b3280ae7ad02daa4da266d7da0754a3d7723b
4
- data.tar.gz: 626ec7cf24c9c746e2cdc39f65acd300e2485330
3
+ metadata.gz: 09e1b556ac3be235df077e4ad203c8bf39074ba2
4
+ data.tar.gz: 51cc893e04a3e59da9a58e942b850c37aed51b6f
5
5
  SHA512:
6
- metadata.gz: 0e813eab6fb0931f8448cdc4c389c44fdc0cf958b32304ac8da870be94b5dd5422a925f1d72327b9c629b825eb41d31b6b88aa8d4f09e55c4d45d1a545880127
7
- data.tar.gz: 77cb11792128cd2dfd458f76fa8f7adc0dbf1f0fed6bddd679a56bdfa5d8a81e93bb207e3f74a316c8b838052ee07c83d530d04a0bd89270dbc282a6de337cb7
6
+ metadata.gz: dd2733444b7330897b0ae12211e413c723b7c17558aa5c5bccad62330a492d8fd907d9cce52e61240789e967a89d0b740e6b6d96561c0836829d3b8a727b1607
7
+ data.tar.gz: 585c68c42645e7dfda6e0ea51d83fb1f3ca73f1f34c4bb0822124b22c5cde7d2ace4f5a828c1ea6c15302664f04a3ce6cd4bbed9a923a7f7e72b1bbeb1a0d726
data/bin/pxlsrt CHANGED
@@ -4,18 +4,30 @@ require 'rubygems'
4
4
  require 'pxlsrt'
5
5
  require 'thor'
6
6
 
7
- class PXLSRT < Thor
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
8
17
  class_option :reverse, :type => :string, :default => "no", :banner => "[no | reverse | either]", :aliases => "-r", :enum => ["no", "reverse", "either"]
9
18
  class_option :vertical, :type => :boolean, :default => false, :aliases => "-v"
10
19
  class_option :diagonal, :type => :boolean, :default => false, :aliases => "-d"
11
20
  class_option :smooth, :type => :boolean, :default => false, :aliases => "-s"
12
21
  class_option :method, :type => :string, :default => "sum-rgb", :banner => "[sum-rgb | red | green | blue | sum-hsb | hue | saturation | brightness | uniqueness | luma | random]", :aliases => "-m", :enum => ["sum-rgb", "red", "green", "blue", "sum-hsb", "hue", "saturation", "brightness", "uniqueness", "luma", "random"]
13
- class_option :diagonal, :type => :boolean, :default => false, :aliases => "-d"
14
22
  class_option :verbose, :type => :boolean, :default => false, :aliases => "-V"
15
23
 
16
24
  option :min, :type => :numeric, :default => Float::INFINITY, :banner => "MINIMUM BANDWIDTH"
17
25
  option :max, :type => :numeric, :default => Float::INFINITY, :banner => "MAXIMUM BANDWIDTH"
18
26
  desc "brute INPUT OUTPUT [options]", "Brute pixel sorting"
27
+ ##
28
+ # Specific options:
29
+ # * min - Minimum bandwidth.
30
+ # * max - Maximum bandwidth.
19
31
  def brute(input, output)
20
32
  k={}
21
33
  for o in options.keys
@@ -28,6 +40,11 @@ class PXLSRT < Thor
28
40
  option :threshold, :type => :numeric, :default => 20, :aliases => "-t"
29
41
  option :edge, :type => :numeric, :default => 2, :aliases => "-e", :banner => "EDGE BUFFERING"
30
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
+ # * edge - Buffers edge.
31
48
  def smart(input, output)
32
49
  k={}
33
50
  for o in options.keys
@@ -37,4 +54,4 @@ class PXLSRT < Thor
37
54
  end
38
55
  end
39
56
 
40
- PXLSRT.start(ARGV)
57
+ CLI.start(ARGV)
data/lib/pxlsrt/brute.rb CHANGED
@@ -2,13 +2,20 @@ require 'rubygems'
2
2
  require 'oily_png'
3
3
 
4
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.
5
8
  class Brute
9
+ ##
10
+ # Uses Pxlsrt::Brute.brute to input and output from one method.
6
11
  def self.suite(inputFileName, outputFileName, trusted, o={})
7
12
  kml=Pxlsrt::Brute.brute(inputFileName, trusted, o)
8
13
  if Pxlsrt::Helpers.contented(kml)
9
14
  kml.save(outputFileName)
10
15
  end
11
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.
12
19
  def self.brute(input, trusted, o={})
13
20
  startTime=Time.now
14
21
  defOptions={
@@ -36,7 +43,17 @@ module Pxlsrt
36
43
  Pxlsrt::Helpers.verbose("Options are all good.") if options[:verbose]
37
44
  if input.class==String
38
45
  Pxlsrt::Helpers.verbose("Getting image from file...") if options[:verbose]
39
- input=ChunkyPNG::Image.from_file(input)
46
+ if File.file?(input)
47
+ if Pxlsrt::Colors.isPNG?(input)
48
+ input=ChunkyPNG::Image.from_file(input)
49
+ else
50
+ Pxlsrt::Helpers.error("File #{input} is not a valid PNG.") if options[:verbose]
51
+ return
52
+ end
53
+ else
54
+ Pxlsrt::Helpers.error("File #{input} doesn't exist!") if options[:verbose]
55
+ return
56
+ end
40
57
  elsif input.class!=String and input.class!=ChunkyPNG::Image
41
58
  Pxlsrt::Helpers.error("Input is not a filename or ChunkyPNG::Image") if options[:verbose]
42
59
  return
data/lib/pxlsrt/colors.rb CHANGED
@@ -1,10 +1,23 @@
1
1
  require "oily_png"
2
2
 
3
3
  module Pxlsrt
4
+ ##
5
+ # Includes color and image operations.
4
6
  class Colors
7
+ ##
8
+ # Converts a ChunkyPNG pixel into an array of the reg, green, and blue values
5
9
  def self.getRGB(pxl)
6
10
  return [ChunkyPNG::Color.r(pxl), ChunkyPNG::Color.g(pxl), ChunkyPNG::Color.b(pxl)]
7
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.read(path).bytes==[137, 80, 78, 71, 10]
16
+ end
17
+ ##
18
+ # ChunkyPNG's rotation was a little slow and doubled runtime.
19
+ # This "rotates" an array, based on the width and height.
20
+ # It uses math and it's really cool, trust me.
8
21
  def self.rotateImage(what, width, height, a)
9
22
  nu=[]
10
23
  case a
@@ -23,9 +36,15 @@ module Pxlsrt
23
36
  end
24
37
  return nu
25
38
  end
39
+ ##
40
+ # Gets "rows" of an array based on a width
26
41
  def self.imageRGBLines(image, width)
27
42
  return image.each_slice(width).to_a
28
43
  end
44
+ ##
45
+ # Outputs random slices of an array.
46
+ # Because of the requirements of pxlsrt, it doesn't actually slice the array, bute returns a range-like array. Example:
47
+ # [[0, 5], [6, 7], [8, 10]]
29
48
  def self.randomSlices(arr, minLength, maxLength)
30
49
  len=arr.length-1
31
50
  if len!=0
@@ -54,9 +73,13 @@ module Pxlsrt
54
73
  end
55
74
  return nu
56
75
  end
76
+ ##
77
+ # This is really lame. Adds first three values of an array together.
57
78
  def self.pxldex(pxl)
58
79
  return pxl[0]+pxl[1]+pxl[2]
59
80
  end
81
+ ##
82
+ # Converts an RGB-like array ([red, green, blue]) into an HSB-like array ([hue, saturation, brightness]).
60
83
  def self.rgb2hsb(rgb)
61
84
  r = rgb[0] / 255.0
62
85
  g = rgb[1] / 255.0
@@ -87,6 +110,8 @@ module Pxlsrt
87
110
  end
88
111
  return [h,s,v]
89
112
  end
113
+ ##
114
+ # Averages an array of RGB-like arrays.
90
115
  def self.colorAverage(ca)
91
116
  if ca.length==1
92
117
  return ca.first
@@ -96,12 +121,18 @@ module Pxlsrt
96
121
  b=((ca.collect { |c| c[2] }).inject{ |sum, el| sum+el }).to_f / ca.size
97
122
  return [r,g,b]
98
123
  end
124
+ ##
125
+ # Determines color distance from each other using the Pythagorean theorem.
99
126
  def self.colorDistance(c1,c2)
100
127
  return Math.sqrt((c1[0]-c2[0])**2+(c1[1]-c2[1])**2+(c1[2]-c2[2])**2)
101
128
  end
129
+ ##
130
+ # Uses a combination of color averaging and color distance to find how "unique" a color is.
102
131
  def self.colorUniqueness(c, ca)
103
132
  return Pxlsrt::Colors.colorDistance(c, Pxlsrt::Colors.colorAverage(ca))
104
133
  end
134
+ ##
135
+ # Sorts an array of colors based on a method.
105
136
  def self.pixelSort(list, how, reverse)
106
137
  mhm=[]
107
138
  case how.downcase
@@ -139,6 +170,8 @@ module Pxlsrt
139
170
  return rand(0..1)==0 ? mhm : mhm.reverse
140
171
  end
141
172
  end
173
+ ##
174
+ # Uses math to turn an array into an array of diagonals.
142
175
  def self.getDiagonals(array, width, height)
143
176
  dias={}
144
177
  for x in (1-height)..(width-1)
@@ -152,6 +185,8 @@ module Pxlsrt
152
185
  end
153
186
  return dias
154
187
  end
188
+ ##
189
+ # Uses math to turn an array of diagonals into a linear array.
155
190
  def self.fromDiagonals(obj, width)
156
191
  ell=[]
157
192
  for k in obj.keys
@@ -173,9 +208,13 @@ module Pxlsrt
173
208
  end
174
209
  return ell
175
210
  end
211
+ ##
212
+ # Turns an RGB-like array into ChunkyPNG's color
176
213
  def self.arrayToRGB(a)
177
214
  return ChunkyPNG::Color.rgb(a[0], a[1], a[2])
178
215
  end
216
+ ##
217
+ # Used in determining Sobel values.
179
218
  def self.sobelate(i, x,y)
180
219
  return ChunkyPNG::Color.to_grayscale_bytes(i[x,y]).first
181
220
  end
@@ -1,14 +1,24 @@
1
1
  module Pxlsrt
2
+ ##
3
+ # Methods not having to do with image or color manipulation.
2
4
  class Helpers
5
+ ##
6
+ # Determines if a value has content.
3
7
  def self.contented(c)
4
8
  return (c.class!=NilClass and ((defined? c)!="nil") and ((/(\S)/.match("#{c}"))!=nil))
5
9
  end
10
+ ##
11
+ # Used to output a red string to the terminal.
6
12
  def self.red(what)
7
13
  return "\e[31m#{what}\e[0m"
8
14
  end
15
+ ##
16
+ # Used to output a cyan string to the terminal.
9
17
  def self.cyan(what)
10
18
  return "\e[36m#{what}\e[0m"
11
19
  end
20
+ ##
21
+ # Checks if supplied options follow the rules.
12
22
  def self.checkOptions(options, rules)
13
23
  match=true
14
24
  for o in options.keys
@@ -39,9 +49,13 @@ module Pxlsrt
39
49
  end
40
50
  return match
41
51
  end
52
+ ##
53
+ # Prints an error message.
42
54
  def self.error(what)
43
55
  puts "#{Pxlsrt::Helpers.red("pxlsrt")} #{what}"
44
56
  end
57
+ ##
58
+ # Prints something.
45
59
  def self.verbose(what)
46
60
  puts "#{Pxlsrt::Helpers.cyan("pxlsrt")} #{what}"
47
61
  end
data/lib/pxlsrt/smart.rb CHANGED
@@ -1,18 +1,22 @@
1
1
  require 'rubygems'
2
2
  require 'oily_png'
3
- require 'json'
4
- require 'pathname'
5
- require 'fileutils'
6
- require 'base64'
7
3
 
8
4
  module Pxlsrt
5
+ ##
6
+ # Smart sorting uses edge-finding algorithms to create bands to sort,
7
+ # as opposed to brute sorting which doesn't care for the content or
8
+ # edges, just a specified range to create bands.
9
9
  class Smart
10
+ ##
11
+ # Uses Pxlsrt::Smart.smart to input and output from pne method.
10
12
  def self.suite(inputFileName, outputFileName, trusted, o={})
11
13
  kml=Pxlsrt::Smart.smart(inputFileName, trusted, o)
12
14
  if Pxlsrt::Helpers.contented(kml)
13
15
  kml.save(outputFileName)
14
16
  end
15
17
  end
18
+ ##
19
+ # The main attraction of the Smart class. Returns a ChunkyPNG::Image that is sorted according to the options provided. Will return nil if it encounters an errors.
16
20
  def self.smart(input, trusted, o={})
17
21
  startTime=Time.now
18
22
  defOptions={
@@ -42,7 +46,17 @@ module Pxlsrt
42
46
  Pxlsrt::Helpers.verbose("Options are all good.") if options[:verbose]
43
47
  if input.class==String
44
48
  Pxlsrt::Helpers.verbose("Getting image from file...") if options[:verbose]
45
- input=ChunkyPNG::Image.from_file(input)
49
+ if File.file?(input)
50
+ if Pxlsrt::Colors.isPNG?(input)
51
+ input=ChunkyPNG::Image.from_file(input)
52
+ else
53
+ Pxlsrt::Helpers.error("File #{input} is not a valid PNG.") if options[:verbose]
54
+ return
55
+ end
56
+ else
57
+ Pxlsrt::Helpers.error("File #{input} doesn't exist!") if options[:verbose]
58
+ return
59
+ end
46
60
  elsif input.class!=String and input.class!=ChunkyPNG::Image
47
61
  Pxlsrt::Helpers.error("Input is not a filename or ChunkyPNG::Image") if options[:verbose]
48
62
  return
@@ -1,3 +1,5 @@
1
+ ##
2
+ # The main module, your best friend.
1
3
  module Pxlsrt
2
- VERSION = "1.0.0"
4
+ VERSION = "1.0.1"
3
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pxlsrt
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - EVA-01
@@ -101,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
101
  version: '0'
102
102
  requirements: []
103
103
  rubyforge_project:
104
- rubygems_version: 2.2.2
104
+ rubygems_version: 2.3.0
105
105
  signing_key:
106
106
  specification_version: 4
107
107
  summary: Pixel sort PNG files.