Class: Pxlsrt::Smart

Inherits:
Object
  • Object
show all
Defined in:
lib/pxlsrt/smart.rb

Overview

Smart sorting uses sorted-finding algorithms to create bands to sort, as opposed to brute sorting which doesn’t care for the content or sorteds, just a specified range to create bands.

Class Method Summary collapse

Class Method Details

.smart(input, o = {}) ⇒ Object

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.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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
# File 'lib/pxlsrt/smart.rb', line 20

def self.smart(input, o={})
  startTime=Time.now
  defOptions={
    :reverse => false,
    :vertical => false,
    :diagonal => false,
    :smooth => false,
    :method => "sum-rgb",
    :verbose => false,
    :absolute => false,
    :threshold => 20,
    :trusted => false,
    :middle => false
  }
  defRules={
    :reverse => :anything,
    :vertical => [false, true],
    :diagonal => [false, true],
    :smooth => [false, true],
    :method => ["sum-rgb", "red", "green", "blue", "sum-hsb", "hue", "saturation", "brightness", "uniqueness", "luma", "random", "cyan", "magenta", "yellow", "alpha", "sum-rgba", "sum-hsba"],
    :verbose => [false, true],
    :absolute => [false, true],
    :threshold => [{:class => [Float, Fixnum]}],
    :trusted => [false, true],
    :middle => :anything
  }
  options=defOptions.merge(o)
  if o.length==0 or options[:trusted]==true or (options[:trusted]==false and o.length!=0 and Pxlsrt::Helpers.checkOptions(options, defRules)!=false)
    Pxlsrt::Helpers.verbose("Options are all good.") if options[:verbose]
    if input.class==String
      Pxlsrt::Helpers.verbose("Getting image from file...") if options[:verbose]
      if File.file?(input)
        if Pxlsrt::Colors.isPNG?(input)
          input=ChunkyPNG::Image.from_file(input)
        else
          Pxlsrt::Helpers.error("File #{input} is not a valid PNG.") if options[:verbose]
          return
        end
      else
        Pxlsrt::Helpers.error("File #{input} doesn't exist!") if options[:verbose]
        return
      end
    elsif input.class!=String and input.class!=ChunkyPNG::Image
      Pxlsrt::Helpers.error("Input is not a filename or ChunkyPNG::Image") if options[:verbose]
      return
    end
    Pxlsrt::Helpers.verbose("Smart mode.") if options[:verbose]
    png=Pxlsrt::Image.new(input)
    if !options[:vertical] and !options[:diagonal]
      Pxlsrt::Helpers.verbose("Retrieving rows") if options[:verbose]
      lines = png.horizontalLines
    elsif options[:vertical] and !options[:diagonal]
      Pxlsrt::Helpers.verbose("Retrieving columns") if options[:verbose]
      lines = png.verticalLines
    elsif !options[:vertical] and options[:diagonal]
      Pxlsrt::Helpers.verbose("Retrieving diagonals") if options[:verbose]
      lines = png.diagonalLines
    elsif options[:vertical] and options[:diagonal]
      Pxlsrt::Helpers.verbose("Retrieving diagonals") if options[:verbose]
      lines = png.rDiagonalLines
    end
    Pxlsrt::Helpers.verbose("Retrieving edges") if options[:verbose]
    png.getSobels
    if !options[:diagonal]
      iterator = 0...(lines.length)
    else
      iterator = lines.keys
    end
    Pxlsrt::Helpers.verbose("Dividing and pixel sorting lines") if options[:verbose]
    for k in iterator
      line = lines[k]
      divisions = []
      division = []
      if line.length > 1
        for pixel in 0...(line.length)
          if !options[:vertical] and !options[:diagonal]
            xy = png.horizontalXY(k, pixel)
          elsif options[:vertical] and !options[:diagonal]
            xy = png.verticalXY(k, pixel)
          elsif !options[:vertical] and options[:diagonal]
            xy = png.diagonalXY(k, pixel)
          elsif options[:vertical] and options[:diagonal]
            xy = png.rDiagonalXY(k, pixel)
          end
          pxlSobel = png.getSobelAndColor(xy["x"], xy["y"])
          if division.length == 0 or (options[:absolute] ? pxlSobel["sobel"] : pxlSobel["sobel"] - division.last["sobel"]) <= options[:threshold]
            division.push(pxlSobel)
          else
            divisions.push(division)
            division = [pxlSobel]
          end
          if pixel == line.length - 1
            divisions.push(division)
            division = []
          end
        end
      end
      newLine = []
      for band in divisions
        newLine.concat(
          Pxlsrt::Helpers.handlePixelSort(
            band.map { |sobelAndColor| sobelAndColor["color"] },
            options
          )
        )
      end
      if !options[:diagonal]
        png.replaceHorizontal(k, newLine) if !options[:vertical]
        png.replaceVertical(k, newLine) if options[:vertical]
      else
        png.replaceDiagonal(k, newLine) if !options[:vertical]
        png.replaceRDiagonal(k, newLine) if options[:vertical]
      end
    end
    endTime=Time.now
    timeElapsed=endTime-startTime
    if timeElapsed < 60
      Pxlsrt::Helpers.verbose("Took #{timeElapsed.round(4)} second#{ timeElapsed.round(4)!=1.0 ? "s" : "" }.") if options[:verbose]
    else
      minutes=(timeElapsed/60).floor
      seconds=(timeElapsed % 60).round(4)
      Pxlsrt::Helpers.verbose("Took #{minutes} minute#{ minutes!=1 ? "s" : "" } and #{seconds} second#{ seconds!=1.0 ? "s" : "" }.") if options[:verbose]
    end
    Pxlsrt::Helpers.verbose("Returning ChunkyPNG::Image...") if options[:verbose]
    return png.returnModified
  else
    Pxlsrt::Helpers.error("Options specified do not follow the correct format.") if options[:verbose]
    return
  end
end

.suite(inputFileName, outputFileName, o = {}) ⇒ Object

Uses Pxlsrt::Smart.smart to input and output from pne method.



12
13
14
15
16
17
# File 'lib/pxlsrt/smart.rb', line 12

def self.suite(inputFileName, outputFileName, o={})
  kml=Pxlsrt::Smart.smart(inputFileName, o)
  if Pxlsrt::Helpers.contented(kml)
    kml.save(outputFileName)
  end
end