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 raise any error that occurs.



19
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
150
151
152
# File 'lib/pxlsrt/smart.rb', line 19

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 => Pxlsrt::Colors::METHODS,
		: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]
					raise "Invalid PNG"
				end
			else
				Pxlsrt::Helpers.error("File #{input} doesn't exist!") if options[:verbose]
				raise "File doesn't exist"
			end
		elsif input.class!=String and input.class!=ChunkyPNG::Image
			Pxlsrt::Helpers.error("Input is not a filename or ChunkyPNG::Image") if options[:verbose]
			raise "Invalid input (must be filename or ChunkyPNG::Image)"
		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
		prr = 0
		len = iterator.to_a.length
		Pxlsrt::Helpers.progress("Dividing and pixel sorting lines", prr, len) 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
			prr += 1
			Pxlsrt::Helpers.progress("Dividing and pixel sorting lines", prr, len) if options[:verbose]
		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]
		raise "Bad options"
	end
end

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

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



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

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