shattered_machine 0.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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +1 -0
- data/.yardoc/checksums +14 -0
- data/.yardoc/complete +0 -0
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/.yardoc/proxy_types +0 -0
- data/Gemfile +8 -0
- data/LICENSE +9 -0
- data/README.md +51 -0
- data/doc/ShatteredMachine.html +135 -0
- data/doc/ShatteredMachine/Brush.html +375 -0
- data/doc/ShatteredMachine/ChangeByte.html +367 -0
- data/doc/ShatteredMachine/Converter.html +327 -0
- data/doc/ShatteredMachine/Defect.html +369 -0
- data/doc/ShatteredMachine/Exchange.html +373 -0
- data/doc/ShatteredMachine/Glitcher.html +365 -0
- data/doc/ShatteredMachine/Io.html +569 -0
- data/doc/ShatteredMachine/Io/Paths.html +310 -0
- data/doc/ShatteredMachine/PixelSorter.html +381 -0
- data/doc/ShatteredMachine/RustyEngine.html +111 -0
- data/doc/ShatteredMachine/Sampler.html +361 -0
- data/doc/ShatteredMachine/Slim.html +389 -0
- data/doc/ShatteredMachine/Transpose.html +369 -0
- data/doc/ShatteredMachine/WrongFilter.html +367 -0
- data/doc/_index.html +288 -0
- data/doc/class_list.html +51 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +58 -0
- data/doc/css/style.css +497 -0
- data/doc/file_list.html +56 -0
- data/doc/frames.html +17 -0
- data/doc/index.html +123 -0
- data/doc/js/app.js +314 -0
- data/doc/js/full_list.js +216 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +275 -0
- data/doc/top-level-namespace.html +110 -0
- data/lib/rusty_engine/librusty_engine.dll +0 -0
- data/lib/rusty_engine/librusty_engine.dylib +0 -0
- data/lib/rusty_engine/librusty_engine.so +0 -0
- data/lib/rusty_engine/rusty_engine.rb +39 -0
- data/lib/shattered_machine.rb +11 -0
- data/lib/shattered_machine/brush.rb +28 -0
- data/lib/shattered_machine/change_byte.rb +41 -0
- data/lib/shattered_machine/converter.rb +20 -0
- data/lib/shattered_machine/defect.rb +38 -0
- data/lib/shattered_machine/exchange.rb +59 -0
- data/lib/shattered_machine/glitcher.rb +35 -0
- data/lib/shattered_machine/io.rb +74 -0
- data/lib/shattered_machine/pixel_sorter.rb +50 -0
- data/lib/shattered_machine/sampler.rb +100 -0
- data/lib/shattered_machine/slim.rb +55 -0
- data/lib/shattered_machine/transpose.rb +50 -0
- data/lib/shattered_machine/wrong_filter.rb +39 -0
- data/shattered_machine.gemspec +16 -0
- data/spec/brush_spec.rb +28 -0
- data/spec/change_byte_spec.rb +26 -0
- data/spec/converter_spec.rb +24 -0
- data/spec/defect_spec.rb +26 -0
- data/spec/exchange_spec.rb +26 -0
- data/spec/glitcher_spec.rb +26 -0
- data/spec/images/bar.PNG +0 -0
- data/spec/images/bar.jpeg +0 -0
- data/spec/images/foo.jpg +0 -0
- data/spec/images/foo.png +0 -0
- data/spec/images/fuzz.JPG +0 -0
- data/spec/images/pouet.JPEG +0 -0
- data/spec/io_spec.rb +74 -0
- data/spec/lib/rusty_engine_spec.rb +20 -0
- data/spec/pixel_sorter_spec.rb +26 -0
- data/spec/sampler_spec.rb +37 -0
- data/spec/slim_spec.rb +26 -0
- data/spec/spec_helper.rb +61 -0
- data/spec/transpose_spec.rb +26 -0
- data/spec/wrong_filter_spec.rb +26 -0
- metadata +147 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../rusty_engine/rusty_engine'
|
4
|
+
|
5
|
+
module ShatteredMachine
|
6
|
+
# Sort pixels of a given png image.
|
7
|
+
# The logic for the pixel sorter come from the Rusty Engine.
|
8
|
+
class PixelSorter
|
9
|
+
# @param options [Hash] options for pixel sort algorithm
|
10
|
+
def initialize(options = {})
|
11
|
+
@direction = options[:direction] || :vertical
|
12
|
+
@smart_sorting = (options[:smart_sorting] || true).to_s
|
13
|
+
@detection_type = options[:detection_type] || :lightness_range
|
14
|
+
@detection_min = options[:detection_min] || '45'
|
15
|
+
@detection_max = options[:detection_max] || '60'
|
16
|
+
@multiple_ranges = (options[:multiple_ranges] || false).to_s
|
17
|
+
@detection_min_2 = options[:detection_min_2] || '75'
|
18
|
+
@detection_max_2 = options[:detection_max_2] || '90'
|
19
|
+
@sorting_by = options[:sorting_by] || :hue
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param input_image [string] path for image
|
23
|
+
# @param output_image [string] path for output pixel sorted image
|
24
|
+
# @return [boolean] status of pixel sort
|
25
|
+
def call(input_image, output_image)
|
26
|
+
RustyEngine.sort(input_image, output_image, rust_formatted_direction, @smart_sorting,
|
27
|
+
rust_formatted_detection_type, @detection_min, @detection_max, @multiple_ranges,
|
28
|
+
@detection_min_2, @detection_max_2, rust_formatted_sorting_by)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def rust_formatted_direction
|
34
|
+
ruby_to_rust_directions = { horizontal: '1', vertical: '2',
|
35
|
+
horizontal_inverted: '3',
|
36
|
+
vertical_inverted: '4' }
|
37
|
+
ruby_to_rust_directions[@direction]
|
38
|
+
end
|
39
|
+
|
40
|
+
def rust_formatted_detection_type
|
41
|
+
ruby_to_rust_detection_type = { lightness_range: '0', colors: '1' }
|
42
|
+
ruby_to_rust_detection_type[@detection_type]
|
43
|
+
end
|
44
|
+
|
45
|
+
def rust_formatted_sorting_by
|
46
|
+
ruby_to_rust_sorting_by = { hue: '0', staturation: '1' }
|
47
|
+
ruby_to_rust_sorting_by[@sorting_by]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pnglitch'
|
4
|
+
module ShatteredMachine
|
5
|
+
# A simple weay ro run one, many or all glitch algotirhm on one specific image.
|
6
|
+
# This create a quick overview of the effect of each algo for the given image.
|
7
|
+
class Sampler
|
8
|
+
FILTERS = %w[none sub up average paeth].freeze
|
9
|
+
SLIM_DIRECTION = %w[up_to_down down_to_up left_to_right right_to_left].freeze
|
10
|
+
BRUSH_DIRECTION = %w[vertical vertical_inverted horizontal horizontal_inverted].freeze
|
11
|
+
ALL_ALGORITHMS = %w[exchange transpose wrong_filter slim brus change_byte defect]
|
12
|
+
|
13
|
+
# @param io [ShatteredMachine::Io] Io containing paths for images to sample
|
14
|
+
# @param options [Hash] options for specifying which
|
15
|
+
def initialize(io, options = {})
|
16
|
+
@io = io
|
17
|
+
@base_output_filename = options[:base_output_filename] || 'sample'
|
18
|
+
@algorithms_to_sample = options[:algorithms_to_sample] || ALL_ALGORITHMS
|
19
|
+
end
|
20
|
+
|
21
|
+
def call
|
22
|
+
FILTERS.each do |filter|
|
23
|
+
sample_exchange(filter)
|
24
|
+
sample_transpose(filter)
|
25
|
+
sample_wrong_filter(filter)
|
26
|
+
end
|
27
|
+
sample_slim
|
28
|
+
sample_brush
|
29
|
+
sample_change_byte
|
30
|
+
sample_defect
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def update_io(output_filename_appendix)
|
36
|
+
@io.output_filename = "#{@base_output_filename}_#{output_filename_appendix}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def sample_exchange(filter)
|
40
|
+
return unless @algorithms_to_sample.include? 'exchange'
|
41
|
+
|
42
|
+
exchange_options = { filter: filter }
|
43
|
+
update_io("exchange_#{filter}")
|
44
|
+
Glitcher.new('Exchange', @io, exchange_options).call
|
45
|
+
end
|
46
|
+
|
47
|
+
def sample_transpose(filter)
|
48
|
+
return unless @algorithms_to_sample.include? 'transpose'
|
49
|
+
|
50
|
+
transpose_options = { filter: filter }
|
51
|
+
update_io("transpose_#{filter}")
|
52
|
+
Glitcher.new('Transpose', @io, transpose_options).call
|
53
|
+
end
|
54
|
+
|
55
|
+
def sample_wrong_filter(filter)
|
56
|
+
return unless @algorithms_to_sample.include? 'wrong_filter'
|
57
|
+
|
58
|
+
wrong_filter_options = { algorithm: 'wrong_filter',
|
59
|
+
filter: filter }
|
60
|
+
update_io("wrong_filter_#{filter}")
|
61
|
+
Glitcher.new('WrongFilter', @io, wrong_filter_options).call
|
62
|
+
end
|
63
|
+
|
64
|
+
def sample_slim
|
65
|
+
return unless @algorithms_to_sample.include? 'slim'
|
66
|
+
|
67
|
+
SLIM_DIRECTION.each do |direction|
|
68
|
+
update_io("slim_#{direction}")
|
69
|
+
slim_options = { direction: direction.to_sym }
|
70
|
+
Glitcher.new('Slim', @io, slim_options).call
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def sample_brush
|
75
|
+
return unless @algorithms_to_sample.include? 'brush'
|
76
|
+
|
77
|
+
BRUSH_DIRECTION.each do |direction|
|
78
|
+
update_io("brush_#{direction}")
|
79
|
+
brush_options = { direction: direction.to_sym }
|
80
|
+
Glitcher.new('Brush', @io, brush_options).call
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def sample_change_byte
|
85
|
+
return unless @algorithms_to_sample.include? 'change_byte'
|
86
|
+
|
87
|
+
update_io("change_byte")
|
88
|
+
change_byte_options = { algorithm: 'change_byte' }
|
89
|
+
Glitcher.new('ChangeByte', @io, change_byte_options).call
|
90
|
+
end
|
91
|
+
|
92
|
+
def sample_defect
|
93
|
+
return unless @algorithms_to_sample.include? 'defect'
|
94
|
+
|
95
|
+
update_io("defect")
|
96
|
+
defect_options = { random: true, iterations: 10 }
|
97
|
+
Glitcher.new('Defect', @io, defect_options).call
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../rusty_engine/rusty_engine'
|
4
|
+
|
5
|
+
module ShatteredMachine
|
6
|
+
# Repeat pixels of a given png image.
|
7
|
+
# The logic for the pixel sorter come from the Rusty Engine.
|
8
|
+
class Slim
|
9
|
+
ALL_COLORS = %i(white black grey red green blue cyan yellow magenta).freeze
|
10
|
+
|
11
|
+
# @param options [Hash] options for slim algorithm
|
12
|
+
def initialize(options = {})
|
13
|
+
@colors = options[:colors] || ALL_COLORS
|
14
|
+
@direction = options[:direction] || :up_to_down
|
15
|
+
@probability = (options[:probability] || 95).to_s
|
16
|
+
@probability_area = options[:probability_area] || 'global'
|
17
|
+
@colors_with_proba = colors_with_proba(options[:colors_with_proba])
|
18
|
+
end
|
19
|
+
|
20
|
+
# @param input_image [string] path for image
|
21
|
+
# @param output_image [string] path for output slimed image
|
22
|
+
# @return [boolean] status of slim
|
23
|
+
def call(input_image, output_image)
|
24
|
+
RustyEngine.slim(input_image, output_image, @probability, @probability_area,
|
25
|
+
rust_formatted_direction, rust_formatted_colors,
|
26
|
+
rust_formatted_color_with_proba)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def colors_with_proba(colors_with_proba_options)
|
32
|
+
if colors_with_proba_options.nil? || colors_with_proba_options.empty?
|
33
|
+
ALL_COLORS.map { |c| [c.to_sym, @probability] }.to_h
|
34
|
+
else
|
35
|
+
colors_with_proba_options
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def rust_formatted_direction
|
40
|
+
ruby_to_rust_directions = { up_to_down: '1', down_to_up: '2',
|
41
|
+
left_to_right: '3', right_to_left: '4' }
|
42
|
+
ruby_to_rust_directions[@direction]
|
43
|
+
end
|
44
|
+
|
45
|
+
def rust_formatted_colors
|
46
|
+
@colors.join(',')
|
47
|
+
end
|
48
|
+
|
49
|
+
def rust_formatted_color_with_proba
|
50
|
+
@colors_with_proba.map do |key, value|
|
51
|
+
"#{key}:#{value}"
|
52
|
+
end.join(',')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pnglitch'
|
4
|
+
module ShatteredMachine
|
5
|
+
# Use the transpose algorithm from pnglitch on a given png image.
|
6
|
+
class Transpose
|
7
|
+
# @param options [Hash] options for transpose algorithm
|
8
|
+
def initialize(options = {})
|
9
|
+
@filter = define_filter(options[:filter]) || 'average'
|
10
|
+
@transpose_force = options[:transpose_force] || 'half'
|
11
|
+
end
|
12
|
+
|
13
|
+
# @param input_image [string] path for image
|
14
|
+
# @param output_image [string] path for output transposed image
|
15
|
+
# @return [boolean] status of transpose
|
16
|
+
def call(input_image, output_image)
|
17
|
+
PNGlitch.open(input_image) do |png|
|
18
|
+
filtered_glitch(png, @filter).save output_image
|
19
|
+
end
|
20
|
+
output_image
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def define_filter(filter_from_options)
|
26
|
+
return filter_from_options unless filter_from_options == 'random'
|
27
|
+
|
28
|
+
available_filters = %w(none sub up average paeth)
|
29
|
+
available_filters[rand(5)]
|
30
|
+
end
|
31
|
+
|
32
|
+
def filtered_glitch(png, custom_filter)
|
33
|
+
png.each_scanline do |scanline|
|
34
|
+
scanline.change_filter custom_filter
|
35
|
+
end
|
36
|
+
png.glitch do |data|
|
37
|
+
transpose_data(data)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def transpose_data(data)
|
42
|
+
x = data.size / 4
|
43
|
+
if @transpose_force == 'half'
|
44
|
+
data[0, x] + data[x * 2, x] + data[x * 1, x] + data[x * 3..-1]
|
45
|
+
else
|
46
|
+
data[x * 2, x] + data[0, x] + data[x * 3..-1] + data[x * 1, x]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pnglitch'
|
4
|
+
module ShatteredMachine
|
5
|
+
# Use the wrong filter algorithm from pnglitch on a given png image.
|
6
|
+
class WrongFilter
|
7
|
+
# @param options [Hash] options for wrong filter algorithm
|
8
|
+
def initialize(options = {})
|
9
|
+
@filter = options[:filter] || 'average'
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param input_image [string] path for image
|
13
|
+
# @param output_image [string] path for output wrong filtered image
|
14
|
+
# @return [boolean] status of wrong filter
|
15
|
+
def call(input_image, output_image)
|
16
|
+
PNGlitch.open(input_image) do |png|
|
17
|
+
filtered_glitch(png, @filter).save output_image
|
18
|
+
end
|
19
|
+
output_image
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def define_random_filter
|
25
|
+
available_filters = %w(none sub up average paeth)
|
26
|
+
available_filters[rand(5)]
|
27
|
+
end
|
28
|
+
|
29
|
+
def filtered_glitch(png, custom_filter)
|
30
|
+
png.each_scanline do |scanline|
|
31
|
+
if custom_filter == 'random'
|
32
|
+
scanline.graft define_random_filter
|
33
|
+
else
|
34
|
+
scanline.graft custom_filter
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'shattered_machine'
|
3
|
+
s.version = '0.0.1'
|
4
|
+
s.summary = 'Shattered Machine core engine'
|
5
|
+
s.description = 'Shattered Machine is an easy way to glitch PNG images using different algorithms'
|
6
|
+
s.authors = ['Flo Girardo']
|
7
|
+
s.email = 'florian@barbrousse.net'
|
8
|
+
s.files = `git ls-files`.split($/)
|
9
|
+
s.test_files = ['spec']
|
10
|
+
s.require_paths = ['lib']
|
11
|
+
s.homepage =
|
12
|
+
'https://glitchedfactory.com/'
|
13
|
+
s.license = 'MIT'
|
14
|
+
s.add_development_dependency('rspec', '~> 3')
|
15
|
+
s.add_development_dependency('yard', '~> 0.9')
|
16
|
+
end
|
data/spec/brush_spec.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# brush_spec.rb
|
2
|
+
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
# brush_spec.rb
|
6
|
+
require 'spec_helper'
|
7
|
+
|
8
|
+
RSpec.describe ShatteredMachine::Brush do
|
9
|
+
describe '#call' do
|
10
|
+
let(:output_file) { 'spec/images/brush.png' }
|
11
|
+
let(:input_file) { 'spec/images/foo.png' }
|
12
|
+
let(:io) do
|
13
|
+
ShatteredMachine::Io.new(input_file, 'spec/images', 'brush')
|
14
|
+
end
|
15
|
+
let(:in_img) { io.png_images.first.input }
|
16
|
+
let(:out_img) { io.png_images.first.output }
|
17
|
+
subject { ShatteredMachine::Brush.new.call(in_img, out_img) }
|
18
|
+
|
19
|
+
after do
|
20
|
+
File.delete(output_file) if File.exist?(output_file)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'brush image' do
|
24
|
+
subject
|
25
|
+
expect(File.exist?(output_file)).to be true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# change_byte_spec.rb
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
RSpec.describe ShatteredMachine::ChangeByte do
|
7
|
+
describe '#call' do
|
8
|
+
let(:output_file) { 'spec/images/change_byte.png' }
|
9
|
+
let(:input_file) { 'spec/images/foo.png' }
|
10
|
+
let(:io) do
|
11
|
+
ShatteredMachine::Io.new(input_file, 'spec/images', 'change_byte')
|
12
|
+
end
|
13
|
+
let(:in_img) { io.png_images.first.input }
|
14
|
+
let(:out_img) { io.png_images.first.output }
|
15
|
+
subject { ShatteredMachine::ChangeByte.new.call(in_img, out_img) }
|
16
|
+
|
17
|
+
after do
|
18
|
+
File.delete(output_file) if File.exist?(output_file)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'change byte on image' do
|
22
|
+
subject
|
23
|
+
expect(File.exist?(output_file)).to be true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# converter.rb
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
RSpec.describe ShatteredMachine::Converter do
|
7
|
+
describe '#call' do
|
8
|
+
let(:converted_file) { 'spec/images/converted.png' }
|
9
|
+
let(:input_file) { 'spec/images/foo.jpg' }
|
10
|
+
let(:io) do
|
11
|
+
ShatteredMachine::Io.new(input_file, 'spec/images', 'converted')
|
12
|
+
end
|
13
|
+
subject { ShatteredMachine::Converter.new(io).call }
|
14
|
+
|
15
|
+
after do
|
16
|
+
File.delete(converted_file) if File.exist?(converted_file)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'convert image' do
|
20
|
+
subject
|
21
|
+
expect(File.exist?(converted_file)).to be true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/spec/defect_spec.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# defect_spec.rb
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
RSpec.describe ShatteredMachine::Defect do
|
7
|
+
describe '#call' do
|
8
|
+
let(:output_file) { 'spec/images/defect.png' }
|
9
|
+
let(:input_file) { 'spec/images/foo.png' }
|
10
|
+
let(:io) do
|
11
|
+
ShatteredMachine::Io.new(input_file, 'spec/images', 'defect')
|
12
|
+
end
|
13
|
+
let(:in_img) { io.png_images.first.input }
|
14
|
+
let(:out_img) { io.png_images.first.output }
|
15
|
+
subject { ShatteredMachine::Defect.new.call(in_img, out_img) }
|
16
|
+
|
17
|
+
after do
|
18
|
+
File.delete(output_file) if File.exist?(output_file)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'defect image' do
|
22
|
+
subject
|
23
|
+
expect(File.exist?(output_file)).to be true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# exchange_spec.rb
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
RSpec.describe ShatteredMachine::Exchange do
|
7
|
+
describe '#call' do
|
8
|
+
let(:output_file) { 'spec/images/exchange.png' }
|
9
|
+
let(:input_file) { 'spec/images/foo.png' }
|
10
|
+
let(:io) do
|
11
|
+
ShatteredMachine::Io.new(input_file, 'spec/images', 'exchange')
|
12
|
+
end
|
13
|
+
let(:in_img) { io.png_images.first.input }
|
14
|
+
let(:out_img) { io.png_images.first.output }
|
15
|
+
subject { ShatteredMachine::Exchange.new.call(in_img, out_img) }
|
16
|
+
|
17
|
+
after do
|
18
|
+
File.delete(output_file) if File.exist?(output_file)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'exchange image' do
|
22
|
+
subject
|
23
|
+
expect(File.exist?(output_file)).to be true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|