shattered_machine 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +34 -0
  3. data/Gemfile +1 -1
  4. data/README.md +19 -0
  5. data/doc/ShatteredMachine.html +5 -7
  6. data/doc/ShatteredMachine/Brush.html +2 -2
  7. data/doc/ShatteredMachine/ChangeByte.html +1 -1
  8. data/doc/ShatteredMachine/Converter.html +2 -2
  9. data/doc/ShatteredMachine/Defect.html +1 -1
  10. data/doc/ShatteredMachine/Exchange.html +1 -1
  11. data/doc/ShatteredMachine/Glitcher.html +13 -13
  12. data/doc/ShatteredMachine/Io.html +23 -44
  13. data/doc/ShatteredMachine/Io/Paths.html +1 -187
  14. data/doc/ShatteredMachine/PixelSorter.html +2 -2
  15. data/doc/ShatteredMachine/ProgressivePixelSorter.html +318 -0
  16. data/doc/ShatteredMachine/Sampler.html +14 -29
  17. data/doc/ShatteredMachine/Slim.html +3 -3
  18. data/doc/ShatteredMachine/Transpose.html +1 -1
  19. data/doc/ShatteredMachine/WrongFilter.html +1 -1
  20. data/doc/_index.html +5 -13
  21. data/doc/class_list.html +1 -1
  22. data/doc/index.html +50 -17
  23. data/doc/method_list.html +48 -48
  24. data/doc/top-level-namespace.html +1 -1
  25. data/icon.png +0 -0
  26. data/icon.svg +122 -0
  27. data/lib/shattered_machine.rb +2 -1
  28. data/lib/shattered_machine/glitcher.rb +8 -0
  29. data/lib/shattered_machine/io.rb +4 -4
  30. data/lib/shattered_machine/pixel_sorter.rb +1 -1
  31. data/lib/shattered_machine/progressive_pixel_sorter.rb +66 -0
  32. data/lib/shattered_machine/sampler.rb +4 -5
  33. data/lib/shattered_machine/slim.rb +4 -2
  34. data/lib/shattered_machine/transpose.rb +2 -2
  35. data/shattered_machine.gemspec +9 -3
  36. metadata +7 -22
  37. data/spec/brush_spec.rb +0 -25
  38. data/spec/change_byte_spec.rb +0 -25
  39. data/spec/converter_spec.rb +0 -23
  40. data/spec/defect_spec.rb +0 -25
  41. data/spec/exchange_spec.rb +0 -25
  42. data/spec/glitcher_spec.rb +0 -25
  43. data/spec/images/bar.PNG +0 -0
  44. data/spec/images/bar.jpeg +0 -0
  45. data/spec/images/foo.jpg +0 -0
  46. data/spec/images/foo.png +0 -0
  47. data/spec/images/fuzz.JPG +0 -0
  48. data/spec/images/pouet.JPEG +0 -0
  49. data/spec/io_spec.rb +0 -73
  50. data/spec/pixel_sorter_spec.rb +0 -25
  51. data/spec/sampler_spec.rb +0 -45
  52. data/spec/slim_spec.rb +0 -25
  53. data/spec/spec_helper.rb +0 -27
  54. data/spec/transpose_spec.rb +0 -25
  55. data/spec/wrong_filter_spec.rb +0 -25
@@ -3,11 +3,12 @@
3
3
  require 'shattered_machine/converter'
4
4
  require 'shattered_machine/glitcher'
5
5
  require 'shattered_machine/io'
6
+ require 'shattered_machine/progressive_pixel_sorter'
6
7
  require 'shattered_machine/sampler'
7
8
 
8
9
  # main file for ShatteredMachine gem
9
10
  module ShatteredMachine
10
- VERSION = '0.0.6'
11
+ VERSION = '0.1.0'
11
12
 
12
13
  class << self
13
14
  end
@@ -1,5 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'brush'
4
+ require_relative 'change_byte'
5
+ require_relative 'defect'
6
+ require_relative 'exchange'
7
+ require_relative 'pixel_sorter'
8
+ require_relative 'slim'
9
+ require_relative 'transpose'
10
+ require_relative 'wrong_filter'
3
11
  module ShatteredMachine
4
12
  # Main class to call from glitching image.
5
13
  class Glitcher
@@ -6,10 +6,6 @@ module ShatteredMachine
6
6
  class Io
7
7
  attr_accessor :output_filename
8
8
 
9
- PNG_EXTENSIONS = ['.png', '.PNG'].freeze
10
- JPG_EXTENSIONS = ['.jpg', '.jpeg', '.JPG', '.JPEG'].freeze
11
- Paths = Struct.new(:input, :output)
12
-
13
9
  # @param input_path [string] input file or directory
14
10
  # @param output_folder [string] output directory
15
11
  # @param output_filename [string] output file name
@@ -39,6 +35,10 @@ module ShatteredMachine
39
35
 
40
36
  private
41
37
 
38
+ PNG_EXTENSIONS = ['.png', '.PNG'].freeze
39
+ JPG_EXTENSIONS = ['.jpg', '.jpeg', '.JPG', '.JPEG'].freeze
40
+ Paths = Struct.new(:input, :output)
41
+
42
42
  def single_image_io
43
43
  [Paths.new(@input_path, generate_output_filename)]
44
44
  end
@@ -43,7 +43,7 @@ module ShatteredMachine
43
43
  end
44
44
 
45
45
  def rust_formatted_sorting_by
46
- ruby_to_rust_sorting_by = { hue: '0', staturation: '1' }
46
+ ruby_to_rust_sorting_by = { hue: '0', saturation: '1' }
47
47
  ruby_to_rust_sorting_by[@sorting_by]
48
48
  end
49
49
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'pixel_sorter'
4
+ module ShatteredMachine
5
+ # Call the pixel sorter multiple time in steps for given png image(s)
6
+ class ProgressivePixelSorter
7
+ # @param io [ShatteredMachine::Io] Io containing paths for images to glitch
8
+ # @param options [Hash] options for the pixel sorting algorithm
9
+ def initialize(io, options)
10
+ @io = io
11
+ @options = options
12
+ @images_count = @io.png_images.count
13
+ @steps = define_steps
14
+ end
15
+
16
+ def call
17
+ @io.png_images.sort_by { |path| [path.input[/\d+/].to_i, path.input] }.each_with_index do |item, index|
18
+ PixelSorter.new(sorter_options(index)).call(item.input, item.output)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def sorter_options(index)
25
+ return @options unless @options[:smart_sorting]
26
+
27
+ step_options = @options.clone
28
+ step_options[:multiple_ranges] = false
29
+ step_options[:detection_min] = (define_new_min_limit(index)).round.to_s
30
+ step_options[:detection_max] = (define_new_max_limit(index)).round.to_s
31
+ step_options
32
+ end
33
+
34
+ def define_steps
35
+ { min: min_step, max: max_step }
36
+ end
37
+
38
+ def min_step
39
+ positive_subtraction(@options[:detection_min].to_f, @options[:detection_min_two].to_f) / (@images_count - 1)
40
+ end
41
+
42
+ def max_step
43
+ positive_subtraction(@options[:detection_max].to_f, @options[:detection_max_two].to_f) / (@images_count - 1)
44
+ end
45
+
46
+ def positive_subtraction(value1, value2)
47
+ value1 > value2 ? value1 - value2 : value2 - value1
48
+ end
49
+
50
+ def define_new_min_limit(index)
51
+ if @options[:detection_min].to_f > @options[:detection_min_two].to_f
52
+ (@options[:detection_min].to_f - (index * @steps[:min]))
53
+ else
54
+ (@options[:detection_min].to_f + (index * @steps[:min]))
55
+ end
56
+ end
57
+
58
+ def define_new_max_limit(index)
59
+ if @options[:detection_max].to_f > @options[:detection_max_two].to_f
60
+ (@options[:detection_max].to_f - (index * @steps[:max]))
61
+ else
62
+ (@options[:detection_max].to_f + (index * @steps[:max]))
63
+ end
64
+ end
65
+ end
66
+ end
@@ -11,7 +11,7 @@ module ShatteredMachine
11
11
  # @param options [Hash] options for specifying which
12
12
  def initialize(io, options = {})
13
13
  @io = io
14
- @base_output_filename = options[:base_output_filename] || 'sample'
14
+ @base_output_filename = io.output_filename.empty? ? 'sample' : io.output_filename
15
15
  @algorithms_to_sample = options[:algorithms_to_sample] || ALL_ALGORITHMS
16
16
  end
17
17
 
@@ -30,8 +30,7 @@ module ShatteredMachine
30
30
  private
31
31
 
32
32
  FILTERS = %w[none sub up average paeth].freeze
33
- SLIM_DIRECTION = %w[up_to_down down_to_up left_to_right right_to_left].freeze
34
- BRUSH_DIRECTION = %w[vertical vertical_inverted horizontal horizontal_inverted].freeze
33
+ DIRECTION = %w[vertical vertical_inverted horizontal horizontal_inverted].freeze
35
34
 
36
35
  def update_io(output_filename_appendix)
37
36
  @io.output_filename = "#{@base_output_filename}_#{output_filename_appendix}"
@@ -65,7 +64,7 @@ module ShatteredMachine
65
64
  def sample_slim
66
65
  return unless @algorithms_to_sample.include? 'slim'
67
66
 
68
- SLIM_DIRECTION.each do |direction|
67
+ DIRECTION.each do |direction|
69
68
  update_io("slim_#{direction}")
70
69
  slim_options = { direction: direction.to_sym }
71
70
  Glitcher.new('Slim', @io, slim_options).call
@@ -75,7 +74,7 @@ module ShatteredMachine
75
74
  def sample_brush
76
75
  return unless @algorithms_to_sample.include? 'brush'
77
76
 
78
- BRUSH_DIRECTION.each do |direction|
77
+ DIRECTION.each do |direction|
79
78
  update_io("brush_#{direction}")
80
79
  brush_options = { direction: direction.to_sym }
81
80
  Glitcher.new('Brush', @io, brush_options).call
@@ -11,7 +11,7 @@ module ShatteredMachine
11
11
  # @param options [Hash] options for slim algorithm
12
12
  def initialize(options = {})
13
13
  @colors = options[:colors] || ALL_COLORS
14
- @direction = options[:direction] || :up_to_down
14
+ @direction = options[:direction] || :vertical_inverted
15
15
  @probability = (options[:probability] || 95).to_s
16
16
  @probability_area = options[:probability_area] || 'global'
17
17
  @colors_with_proba = colors_with_proba(options[:colors_with_proba])
@@ -38,7 +38,9 @@ module ShatteredMachine
38
38
 
39
39
  def rust_formatted_direction
40
40
  ruby_to_rust_directions = { up_to_down: '1', down_to_up: '2',
41
- left_to_right: '3', right_to_left: '4' }
41
+ left_to_right: '3', right_to_left: '4',
42
+ vertical: '1', vertical_inverted: '2',
43
+ horizontal: '3', horizontal_inverted: '4' }
42
44
  ruby_to_rust_directions[@direction]
43
45
  end
44
46
 
@@ -47,11 +47,11 @@ module ShatteredMachine
47
47
  end
48
48
 
49
49
  def half_transpose(data, qis)
50
- data[0, qis] + data[qis * 2, qis] + data[qis * 1, qis] + data[qis * 3..]
50
+ data[0, qis] + data[qis * 2, qis] + data[qis * 1, qis] + data[qis * 3..-1]
51
51
  end
52
52
 
53
53
  def full_transpose(data, qis)
54
- data[qis * 2, qis] + data[0, qis] + data[qis * 3..] + data[qis * 1, qis]
54
+ data[qis * 2, qis] + data[0, qis] + data[qis * 3..-1] + data[qis * 1, qis]
55
55
  end
56
56
  end
57
57
  end
@@ -1,17 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
4
+
1
5
  Gem::Specification.new do |s|
2
6
  s.name = 'shattered_machine'
3
- s.version = '0.0.6'
7
+ s.version = '0.1.0'
4
8
  s.required_ruby_version = '>= 2.0.0'
5
9
  s.required_rubygems_version = '>= 1.8.11'
6
10
  s.summary = 'Shattered Machine core engine'
7
11
  s.description = 'Shattered Machine is an easy way to glitch PNG images using different algorithms'
8
12
  s.authors = ['Flo Girardo']
9
13
  s.email = 'florian@barbrousse.net'
10
- s.files = `git ls-files`.split($/)
14
+ s.files = `git ls-files`.split($RS).reject do |file|
15
+ file =~ %r{^spec/}
16
+ end
11
17
  s.test_files = ['spec']
12
18
  s.require_paths = ['lib']
13
19
  s.homepage =
14
- 'https://framagit.org/Radoteur/shattered-machine'
20
+ 'https://git.sr.ht/~pouet/shattered_machine'
15
21
  s.license = 'MIT'
16
22
  s.add_dependency 'rusty_engine_ffi', '>=0.0.2'
17
23
  s.add_development_dependency('rspec', '~> 3')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shattered_machine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Flo Girardo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-28 00:00:00.000000000 Z
11
+ date: 2021-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rusty_engine_ffi
@@ -75,6 +75,7 @@ files:
75
75
  - doc/ShatteredMachine/Io.html
76
76
  - doc/ShatteredMachine/Io/Paths.html
77
77
  - doc/ShatteredMachine/PixelSorter.html
78
+ - doc/ShatteredMachine/ProgressivePixelSorter.html
78
79
  - doc/ShatteredMachine/Sampler.html
79
80
  - doc/ShatteredMachine/Slim.html
80
81
  - doc/ShatteredMachine/Transpose.html
@@ -92,6 +93,8 @@ files:
92
93
  - doc/js/jquery.js
93
94
  - doc/method_list.html
94
95
  - doc/top-level-namespace.html
96
+ - icon.png
97
+ - icon.svg
95
98
  - lib/shattered_machine.rb
96
99
  - lib/shattered_machine/brush.rb
97
100
  - lib/shattered_machine/change_byte.rb
@@ -101,31 +104,13 @@ files:
101
104
  - lib/shattered_machine/glitcher.rb
102
105
  - lib/shattered_machine/io.rb
103
106
  - lib/shattered_machine/pixel_sorter.rb
107
+ - lib/shattered_machine/progressive_pixel_sorter.rb
104
108
  - lib/shattered_machine/sampler.rb
105
109
  - lib/shattered_machine/slim.rb
106
110
  - lib/shattered_machine/transpose.rb
107
111
  - lib/shattered_machine/wrong_filter.rb
108
112
  - shattered_machine.gemspec
109
- - spec/brush_spec.rb
110
- - spec/change_byte_spec.rb
111
- - spec/converter_spec.rb
112
- - spec/defect_spec.rb
113
- - spec/exchange_spec.rb
114
- - spec/glitcher_spec.rb
115
- - spec/images/bar.PNG
116
- - spec/images/bar.jpeg
117
- - spec/images/foo.jpg
118
- - spec/images/foo.png
119
- - spec/images/fuzz.JPG
120
- - spec/images/pouet.JPEG
121
- - spec/io_spec.rb
122
- - spec/pixel_sorter_spec.rb
123
- - spec/sampler_spec.rb
124
- - spec/slim_spec.rb
125
- - spec/spec_helper.rb
126
- - spec/transpose_spec.rb
127
- - spec/wrong_filter_spec.rb
128
- homepage: https://framagit.org/Radoteur/shattered-machine
113
+ homepage: https://git.sr.ht/~pouet/shattered_machine
129
114
  licenses:
130
115
  - MIT
131
116
  metadata: {}
data/spec/brush_spec.rb DELETED
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe ShatteredMachine::Brush do
6
- describe '#call' do
7
- let(:output_file) { 'spec/images/brush.png' }
8
- let(:input_file) { 'spec/images/foo.png' }
9
- let(:io) do
10
- ShatteredMachine::Io.new(input_file, 'spec/images', 'brush')
11
- end
12
- let(:in_img) { io.png_images.first.input }
13
- let(:out_img) { io.png_images.first.output }
14
- subject { ShatteredMachine::Brush.new.call(in_img, out_img) }
15
-
16
- after do
17
- File.delete(output_file) if File.exist?(output_file)
18
- end
19
-
20
- it 'brush image' do
21
- subject
22
- expect(File.exist?(output_file)).to be true
23
- end
24
- end
25
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe ShatteredMachine::ChangeByte do
6
- describe '#call' do
7
- let(:output_file) { 'spec/images/change_byte.png' }
8
- let(:input_file) { 'spec/images/foo.png' }
9
- let(:io) do
10
- ShatteredMachine::Io.new(input_file, 'spec/images', 'change_byte')
11
- end
12
- let(:in_img) { io.png_images.first.input }
13
- let(:out_img) { io.png_images.first.output }
14
- subject { ShatteredMachine::ChangeByte.new.call(in_img, out_img) }
15
-
16
- after do
17
- File.delete(output_file) if File.exist?(output_file)
18
- end
19
-
20
- it 'change byte on image' do
21
- subject
22
- expect(File.exist?(output_file)).to be true
23
- end
24
- end
25
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe ShatteredMachine::Converter do
6
- describe '#call' do
7
- let(:converted_file) { 'spec/images/converted.png' }
8
- let(:input_file) { 'spec/images/foo.jpg' }
9
- let(:io) do
10
- ShatteredMachine::Io.new(input_file, 'spec/images', 'converted')
11
- end
12
- subject { ShatteredMachine::Converter.new(io).call }
13
-
14
- after do
15
- File.delete(converted_file) if File.exist?(converted_file)
16
- end
17
-
18
- it 'convert image' do
19
- subject
20
- expect(File.exist?(converted_file)).to be true
21
- end
22
- end
23
- end
data/spec/defect_spec.rb DELETED
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe ShatteredMachine::Defect do
6
- describe '#call' do
7
- let(:output_file) { 'spec/images/defect.png' }
8
- let(:input_file) { 'spec/images/foo.png' }
9
- let(:io) do
10
- ShatteredMachine::Io.new(input_file, 'spec/images', 'defect')
11
- end
12
- let(:in_img) { io.png_images.first.input }
13
- let(:out_img) { io.png_images.first.output }
14
- subject { ShatteredMachine::Defect.new.call(in_img, out_img) }
15
-
16
- after do
17
- File.delete(output_file) if File.exist?(output_file)
18
- end
19
-
20
- it 'defect image' do
21
- subject
22
- expect(File.exist?(output_file)).to be true
23
- end
24
- end
25
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe ShatteredMachine::Exchange do
6
- describe '#call' do
7
- let(:output_file) { 'spec/images/exchange.png' }
8
- let(:input_file) { 'spec/images/foo.png' }
9
- let(:io) do
10
- ShatteredMachine::Io.new(input_file, 'spec/images', 'exchange')
11
- end
12
- let(:in_img) { io.png_images.first.input }
13
- let(:out_img) { io.png_images.first.output }
14
- subject { ShatteredMachine::Exchange.new.call(in_img, out_img) }
15
-
16
- after do
17
- File.delete(output_file) if File.exist?(output_file)
18
- end
19
-
20
- it 'exchange image' do
21
- subject
22
- expect(File.exist?(output_file)).to be true
23
- end
24
- end
25
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe ShatteredMachine::Glitcher do
6
- describe '#call' do
7
- let(:output_file) { 'spec/images/glitch.png' }
8
- let(:input_file) { 'spec/images/foo.png' }
9
- let(:io) do
10
- ShatteredMachine::Io.new(input_file, 'spec/images', 'glitch')
11
- end
12
- subject do
13
- ShatteredMachine::Glitcher.new('Slim', io).call
14
- end
15
-
16
- after do
17
- File.delete(output_file) if File.exist?(output_file)
18
- end
19
-
20
- it 'slim image' do
21
- subject
22
- expect(File.exist?(output_file)).to be true
23
- end
24
- end
25
- end