pixel_dreamer 0.1.0
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 +9 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/pixel_dreamer/constants.rb +58 -0
- data/lib/pixel_dreamer/version.rb +3 -0
- data/lib/pixel_dreamer.rb +385 -0
- data/pixel_dreamer.gemspec +33 -0
- data/support/test.png +0 -0
- metadata +170 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bd26f59d7a1d5b000efc49e3d0a6f9557422fa06
|
4
|
+
data.tar.gz: 3f216b77ff97cb19aea96902cb707a6c2c537dcc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7ec303bcd960e9bba23a73cee66d94dbe92a9de7bc33cdab6368b34adbce0853d7c09610f7162b2c9f904d65f93c2af75216145853302286506365da90efdc37
|
7
|
+
data.tar.gz: b4d07a410323093332d04a6424ed35c006fc63bf523ef1eb2deaa4233073088e8f8ff14fb7349a97ba013d9aaa7ca16959c46c6bbe4d1dca9a59de8fc9d0ec2b
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Christian Samuel
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# PixelDreamer
|
2
|
+
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/pixel_dreamer`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
|
+
|
5
|
+
TODO: Delete this and the text above, and describe your gem
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'pixel_dreamer'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install pixel_dreamer
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
+
|
31
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/pixel_dreamer.
|
36
|
+
|
37
|
+
|
38
|
+
## License
|
39
|
+
|
40
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
41
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "pixel_dreamer"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module PixelDreamer
|
2
|
+
module Constants
|
3
|
+
SETTINGS = {sharp: {verbose: true, vertical: true, min: 20, max: 60, method: 'uniqueness'},
|
4
|
+
soft: {verbose: true, vertical: true, min: 100, max: 300},
|
5
|
+
soft_diagonal: {verbose: true, diagonal: true, min: 100, max: 300},
|
6
|
+
side_glitch: {verbose: true, vertical: false, min: 40, middle: -1},
|
7
|
+
side_glitch_soft: {verbose: true, vertical: false, min: 100, max: 300, middle: -1},
|
8
|
+
side_glitch_erratic: {verbose: true, vertical: false, min: 100, max: 300, middle: -4},
|
9
|
+
vertical_glitch_soft: {verbose: true, vertical: true, min: 100, max: 300, middle: -1},
|
10
|
+
soft_unique: {verbose: true, vertical: true, min: 100, max: 300, method: 'uniqueness'},
|
11
|
+
side_soft_unique: {verbose: true, vertical: false, min: 100, max: 300, method: 'uniqueness'},
|
12
|
+
side_soft_aggressive: {verbose: true, vertical: false, min: 100, max: 300, method: 'sum-hsb', smooth: true},
|
13
|
+
side_soft_harsh: {verbose: true, vertical: false, min: 100, max: 300, method: 'hue', smooth: true},
|
14
|
+
side_soft_sand: {verbose: true, vertical: false, min: 100, max: 300, method: 'random', smooth: true},
|
15
|
+
side_soft_yellow: {verbose: true, vertical: false, min: 100, max: 300, method: 'yellow', smooth: true},
|
16
|
+
soft_reverse: {verbose: true, vertical: true, min: 100, max: 300, reverse: true},
|
17
|
+
soft_min: {verbose: true, diagonal: true, max: 6},
|
18
|
+
cinna: {verbose: true, vertical: true, min: 150, max: 300},
|
19
|
+
cami: {verbose: true, vertical: true, min: 60, max: 120}}
|
20
|
+
|
21
|
+
SORTING_METHODS = ['sum-rgb', 'red', 'green', 'blue', 'sum-hsb', 'hue', 'saturation', 'brightness', 'uniqueness',
|
22
|
+
'luma', 'random', 'magenta', 'cyan', 'yellow', 'alpha', 'sum-rgba', 'sum-hsba', 'none']
|
23
|
+
|
24
|
+
RANDOMIZE_SETTINGS = {reverse: [true, false], vertical: [true, false], diagonal: [true, false],
|
25
|
+
smooth: [true, false], method: SORTING_METHODS, min: (1..1000).to_a,
|
26
|
+
max: (1..1000).to_a, trusted: [true, false], middle: [true, false], verbose: [true]}
|
27
|
+
|
28
|
+
RANDOMIZE_DEFAULTS = {gif: false, compress: true, speed: 84, image_number: 10}
|
29
|
+
|
30
|
+
SEQUENCE_SETTINGS = {high_long: {counter: 1, max_multiple: 3, increment: 1, break_point: 101},
|
31
|
+
high_short: {counter: 1, max_multiple: 3, increment: 1, break_point: 31},
|
32
|
+
high_short_late: {counter: 70, max_multiple: 3, increment: 1, break_point: 101},
|
33
|
+
cinna: {counter: 120, max_multiple: 2, increment: 1, break_point: 151},
|
34
|
+
cami: {counter: 60, max_multiple: 2, increment: 1, break_point: 91},
|
35
|
+
high_short_late_middle: {counter: 45, max_multiple: 3, increment: 1, break_point: 76},
|
36
|
+
high_short_early: {counter: 20, max_multiple: 3, increment: 1, break_point: 51},
|
37
|
+
low_short: {counter: 1, max_multiple: 3, increment: 3, break_point: 31},
|
38
|
+
low_long: {counter: 1, max_multiple: 3, increment: 3, break_point: 101}}
|
39
|
+
|
40
|
+
DEFAULTS = {reverse: false, vertical: false, diagonal: false,
|
41
|
+
smooth: false, method: 'sum-rgb', verbose: false,
|
42
|
+
min: Float::INFINITY, max: Float::INFINITY,
|
43
|
+
trusted: false, middle: false}
|
44
|
+
|
45
|
+
GLITCH_SEQUENCE_DEFAULTS = {settings: SETTINGS[:soft], sequence_settings: SEQUENCE_SETTINGS[:high_short],
|
46
|
+
compress: true, speed: 84}
|
47
|
+
|
48
|
+
BARRAGE_DEFAULTS = {gif: false, compress: true, speed: 84}
|
49
|
+
|
50
|
+
BRUTE_SORT_SAVE_WITH_SETTINGS_DEFAULTS = {settings: {}, output_name: nil, gif: false,
|
51
|
+
output_folder: false}
|
52
|
+
IMAGE_DELAY_DEFAULTS = {active: false, image_to_delay: 1, delay_length: 1000}
|
53
|
+
|
54
|
+
DITHER_DEFAULTS = {active: false, number_of_colors: 200}
|
55
|
+
|
56
|
+
GIF_DEFAULTS = {speed: 84, dither: DITHER_DEFAULTS, image_delay: IMAGE_DELAY_DEFAULTS}
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,385 @@
|
|
1
|
+
require 'pixel_dreamer/version'
|
2
|
+
require 'pxlsrt'
|
3
|
+
require 'rmagick'
|
4
|
+
require 'image_optim'
|
5
|
+
require 'image_optim_pack'
|
6
|
+
require 'pixel_dreamer/constants'
|
7
|
+
|
8
|
+
##
|
9
|
+
# to use pixel dreamer you must first create a new PixelDreamer::Image class
|
10
|
+
# to do this you must pass in the uri of the image you will be pixel sorting
|
11
|
+
# example: image = PixelDreamer::Image.new('/uri/image.png')
|
12
|
+
# now you can use the instance methods
|
13
|
+
|
14
|
+
|
15
|
+
module PixelDreamer
|
16
|
+
class ImageDreamer
|
17
|
+
include Magick
|
18
|
+
attr_accessor :image
|
19
|
+
|
20
|
+
def initialize(image)
|
21
|
+
|
22
|
+
@image = prepare_image(image)
|
23
|
+
@input_name = name_parser(image)
|
24
|
+
@parent_path = parent_path(image)
|
25
|
+
@sequence_folder = sequence_folder
|
26
|
+
@sequence_frame_path = sequence_frame_path
|
27
|
+
@image_path = image_path
|
28
|
+
@output_folder = output_folder
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# converts image to png
|
33
|
+
def convert_to_png(image_uri)
|
34
|
+
path_without_ext = File.join(File.dirname(image_uri), File.basename(image_uri, '.*'))
|
35
|
+
end_image = path_without_ext + '.png'
|
36
|
+
image = Image.read(image_uri).first
|
37
|
+
image.write(end_image)
|
38
|
+
end_image
|
39
|
+
end
|
40
|
+
|
41
|
+
# pixel sorts on image
|
42
|
+
# by default blah blah blah
|
43
|
+
# to lazy to write the documentation rn
|
44
|
+
# read the documentation from the other methods to get an idea
|
45
|
+
# also read the documentation for pxlsrt
|
46
|
+
def brute_sort_save_with_settings(options = {})
|
47
|
+
options[:image] ||= @image
|
48
|
+
options = Constants::BRUTE_SORT_SAVE_WITH_SETTINGS_DEFAULTS.merge(options)
|
49
|
+
image = options[:image]
|
50
|
+
settings = Constants::DEFAULTS.merge(options[:settings])
|
51
|
+
output_name = options[:output_name]
|
52
|
+
gif = options[:gif]
|
53
|
+
output_folder = options[:output_folder]
|
54
|
+
|
55
|
+
Pxlsrt::Brute.brute(image, reverse: settings[:reverse], vertical: settings[:vertical],
|
56
|
+
diagonal: settings[:diagonal], smooth: settings[:smooth], method: settings[:method],
|
57
|
+
verbose: settings[:verbose], min: settings[:min], max: settings[:max],
|
58
|
+
trusted: settings[:trusted], middle: settings[:middle]
|
59
|
+
).save(file_name_with_settings(image, settings, output_name, gif, output_folder))
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# creates a sequence of pixel sorted images based on the setting hash and a sequence_setting hash chosen
|
64
|
+
# once the image has been instantiated you can run this method without passing in any parameters
|
65
|
+
# by default it is executed with these settings:
|
66
|
+
# settings: SETTINGS[:soft], sequence_settings: SEQUENCE_SETTINGS[:high_short], compress: true, speed: 84
|
67
|
+
# example: image.glitch_sequence
|
68
|
+
# or with parameters, an output name can be passed in as well (string)
|
69
|
+
# image.glitch_sequence({ settings: SETTINGS[:sharp], sequence_settings: SEQUENCE_SETTINGS[:high_long],
|
70
|
+
# compress: false, speed: 42, output_name: 'image_glitched' })
|
71
|
+
# the output name must only include the name of the output image not the file extension
|
72
|
+
# this creates a sequence of of images that have been pixel sorted in with increments specified
|
73
|
+
#
|
74
|
+
# the settings_hash can be pulled from the SETTINGS, defaults to SETTINGS[:soft]
|
75
|
+
# the sequence_settings cans be pulled from the SEQUENCE_SETTINGS, defaults to SEQUENCE_SETTINGS[:high_short]
|
76
|
+
# compress defaults to true, copies and compresses input file and creates sequence from compressed file
|
77
|
+
# the fps is set by the speed which is in milliseconds, defaults to 84ms (12fps)
|
78
|
+
# the uri_helper method can be used to create the input uri
|
79
|
+
def glitch_sequence(options = {})
|
80
|
+
options[:output_name] ||= @input_name
|
81
|
+
options = Constants::GLITCH_SEQUENCE_DEFAULTS.merge(options)
|
82
|
+
settings = options[:settings]
|
83
|
+
sequence_settings = options[:sequence_settings]
|
84
|
+
output_name = options[:output_name]
|
85
|
+
counter = sequence_settings[:counter]
|
86
|
+
prepare(counter, options[:compress])
|
87
|
+
puts 'Begin glitch sequence.'
|
88
|
+
|
89
|
+
image_number = 1
|
90
|
+
while counter < sequence_settings[:break_point]
|
91
|
+
settings[:min] = counter
|
92
|
+
settings[:max] = counter * sequence_settings[:max_multiple]
|
93
|
+
brute_sort_save_with_settings(image: @path, settings: settings, output_name: (output_name + "_#{image_number}"),
|
94
|
+
gif: true, output_folder: true)
|
95
|
+
puts "IMAGE #{image_number}/#{sequence_settings[:break_point] - sequence_settings[:counter]} COMPLETE"
|
96
|
+
image_number += 1
|
97
|
+
counter += sequence_settings[:increment]
|
98
|
+
end
|
99
|
+
gif(options)
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
##
|
104
|
+
# creates an image for each setting from the settings hash
|
105
|
+
# quickest way to see how all of the settings effect the image supplied
|
106
|
+
# once the image has been instantiated you can run this method without passing in any parameters
|
107
|
+
# by default it is executed with these settings:
|
108
|
+
# gif: false, compress: true, speed: 84
|
109
|
+
#
|
110
|
+
# example: image.barrage
|
111
|
+
# or with parameters, an output name (string) can be passed in as well
|
112
|
+
# image.barrage({ gif: true, compress: false, speed: 42, output_name: 'image_glitched' })
|
113
|
+
#
|
114
|
+
# the output name must only include the name of the output image not the file extension
|
115
|
+
# the uri_helper can be used to create the input uri
|
116
|
+
# example using the uri_helper:
|
117
|
+
def barrage(options = {})
|
118
|
+
options[:output_name] ||= @input_name
|
119
|
+
options = Constants::BARRAGE_DEFAULTS.merge(options)
|
120
|
+
output_name = options[:output_name]
|
121
|
+
gif = options[:gif]
|
122
|
+
counter = 1
|
123
|
+
prepare(counter, options[:compress])
|
124
|
+
puts 'Begin barrage.'
|
125
|
+
|
126
|
+
Constants::SETTINGS.each do |key, setting_hash|
|
127
|
+
brute_sort_save_with_settings(image: image, settings: setting_hash, output_name: (output_name + "_#{key}"),
|
128
|
+
gif: gif, output_folder: true)
|
129
|
+
puts "Image #{counter}/#{Constants::SETTINGS.length} complete."
|
130
|
+
counter += 1
|
131
|
+
end
|
132
|
+
gif(options) if gif
|
133
|
+
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# creates a series of images that are pixel sorted with randomized settings
|
137
|
+
# the output is very hectic
|
138
|
+
# once the image has been instantiated you can run this method without passing in any parameters
|
139
|
+
# by default it is executed with these settings:
|
140
|
+
# gif: false, compress: true, speed: 84, image_number: 10
|
141
|
+
#
|
142
|
+
# example: image.randomize
|
143
|
+
# or with parameters, an output name (string) can be passed in as well
|
144
|
+
# image.randomize({ gif: trues, compress: false, speed: 42, image_number: 20, output_name: 'image_glitched' })
|
145
|
+
#
|
146
|
+
# the output name must only include the name of the output image not the file extension
|
147
|
+
# the amount of images that are created are based on the image_number (integer)
|
148
|
+
def randomize(options = {})
|
149
|
+
options[:output_name] ||= @input_name
|
150
|
+
options = Constants::RANDOMIZE_DEFAULTS.merge(options)
|
151
|
+
prepare(1, options[:compress])
|
152
|
+
puts 'Being randomizing.'
|
153
|
+
|
154
|
+
options[:image_number].times do
|
155
|
+
brute_sort_save_with_settings(image: image, settings: randomize_settings, output_name: (options[:output_name] + random_name),
|
156
|
+
gif: options[:gif], output_folder: true)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# copies and compresses file passed
|
162
|
+
# cannot compress b&w images
|
163
|
+
def compress(img, path)
|
164
|
+
puts 'Compressing image.'
|
165
|
+
image_optim = ImageOptim.new(allow_lossy: true, verbose: false, skip_missing_workers: true, optipng: false,
|
166
|
+
pngcrush: false, pngquant: { allow_lossy: true },
|
167
|
+
advpng: false, pngout: false, svgo: false)
|
168
|
+
File.rename(image_optim.optimize_image(img), path)
|
169
|
+
puts 'Image copied and compressed.'
|
170
|
+
end
|
171
|
+
|
172
|
+
##
|
173
|
+
# creates a gif using the @sequence_folder path and outputs gif into the @output_folder path
|
174
|
+
# once the image has been instantiated you can run this method without passing in any parameters
|
175
|
+
# by default it is executed with these settings:
|
176
|
+
# speed: 84, dither: DITHER_DEFAULTS, image_delay: IMAGE_DELAY_DEFAULTS
|
177
|
+
#
|
178
|
+
# example: image.gif
|
179
|
+
# or with parameters, an output name (string) can be passed in as well
|
180
|
+
# image.gif({speed: 42, dither: DITHER_DEFAULTS, image_delay: IMAGE_DELAY_DEFAULTS, output_name: 'image_gif'})
|
181
|
+
#
|
182
|
+
# or image.gif({speed: 42, dither: {active: false, number_of_colors: 200},
|
183
|
+
# image_delay: {active: false, image_to_delay: 1, delay_length: 1000}, output_name: 'image_gif'})
|
184
|
+
#
|
185
|
+
# speed is used to set the length of time for each frame of the gif, it defaults to milliseconds
|
186
|
+
# - 12 fps: length of frame = 84 ms
|
187
|
+
# - 24 fps: length of frame = 42 ms
|
188
|
+
# - 30 fps: length of frame = 33 ms
|
189
|
+
# - 60 fps: length of frame = 17 ms
|
190
|
+
# the dither hash used to set the dither settings
|
191
|
+
# the image_delay hash is used to pause the sequence on an image for a set amount of time
|
192
|
+
def gif(options = {})
|
193
|
+
options[:output_name] ||= @input_name
|
194
|
+
options = Constants::GIF_DEFAULTS.merge(options)
|
195
|
+
options[:image_delay] = Constants::IMAGE_DELAY_DEFAULTS.merge(options[:image_delay])
|
196
|
+
options[:dither] = Constants::DITHER_DEFAULTS.merge(options[:dither])
|
197
|
+
image_delay = options[:image_delay]
|
198
|
+
dither = options[:dither]
|
199
|
+
animation = ImageList.new(*Dir["#{@sequence_folder}*.png"].sort_by { |x| x[/\d+/].to_i })
|
200
|
+
animation.ticks_per_second=1000
|
201
|
+
puts 'Got images.'
|
202
|
+
animation.delay = options[:speed]
|
203
|
+
animation[(image_delay[:image_to_delay] - 1)].delay = image_delay[:delay_length] if image_delay[:active]
|
204
|
+
puts 'Creating GIF.'
|
205
|
+
animation = dither(animation, dither[:number_of_colors]) if dither[:active]
|
206
|
+
animation.write("#{@output_folder}#{options[:output_name]}.gif")
|
207
|
+
puts 'Complete.'
|
208
|
+
end
|
209
|
+
|
210
|
+
##
|
211
|
+
# creates a uri by adding the name to common paths
|
212
|
+
# example: test = uri_helper('desktop', 'test.png')
|
213
|
+
def self.uri_helper(location, file_name)
|
214
|
+
"/Users/#{ENV['USER']}/#{location}/" + file_name
|
215
|
+
end
|
216
|
+
|
217
|
+
private
|
218
|
+
|
219
|
+
##
|
220
|
+
# checks if image is png, if it is, returns the uri passed else it converts to png
|
221
|
+
def prepare_image(image_uri)
|
222
|
+
if image_png?(image_uri)
|
223
|
+
image_uri
|
224
|
+
else
|
225
|
+
convert_to_png(image_uri)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
##
|
230
|
+
# check if image is png
|
231
|
+
def image_png?(image_uri)
|
232
|
+
File.extname(image_uri) == '.png'
|
233
|
+
end
|
234
|
+
|
235
|
+
def randomize_settings
|
236
|
+
hash = {}
|
237
|
+
Constants::RANDOMIZE_SETTINGS.each do |key, setting|
|
238
|
+
setting.sample
|
239
|
+
hash[key] = setting.sample
|
240
|
+
end
|
241
|
+
hash
|
242
|
+
end
|
243
|
+
|
244
|
+
def random_name
|
245
|
+
'_' + (0...4).map { 65.+(rand(26)).chr }.join.downcase
|
246
|
+
end
|
247
|
+
|
248
|
+
def dither(animation, number_of_colors)
|
249
|
+
animation.quantize(number_colors=number_of_colors,
|
250
|
+
colorspace=RGBColorspace, dither=RiemersmaDitherMethod,
|
251
|
+
tree_depth=0, measure_error=false)
|
252
|
+
end
|
253
|
+
|
254
|
+
def prepare(counter, compress)
|
255
|
+
make_dir?
|
256
|
+
path_selector(counter, compress, image)
|
257
|
+
compress(image, @path) if compress
|
258
|
+
end
|
259
|
+
|
260
|
+
##
|
261
|
+
# creates an instance variable with the name from the file/uri passed
|
262
|
+
# example: name_parser('/Users/user/desktop/test.png') => @input_name = 'test'
|
263
|
+
# only .png files can be passed
|
264
|
+
def name_parser(uri)
|
265
|
+
base_uri = uri.dup
|
266
|
+
File.basename(base_uri, '.*')
|
267
|
+
end
|
268
|
+
|
269
|
+
##
|
270
|
+
# creates an instance variable with the parent directory of the file path passed
|
271
|
+
# example: path('/Users/user/desktop/test.png') => @parent_path = '/Users/user/desktop/'
|
272
|
+
# can only be run after the name_parser
|
273
|
+
def parent_path(uri)
|
274
|
+
parent_path = uri.dup
|
275
|
+
length = @input_name.length + 4
|
276
|
+
uri_length = parent_path.length
|
277
|
+
start = uri_length - length
|
278
|
+
parent_path[start..uri_length] = ''
|
279
|
+
parent_path
|
280
|
+
end
|
281
|
+
|
282
|
+
def output_folder
|
283
|
+
"#{@parent_path}output/#{@input_name}/"
|
284
|
+
end
|
285
|
+
|
286
|
+
|
287
|
+
##
|
288
|
+
# creates an instance variable with the parent directory of the output
|
289
|
+
# example: output_folder => @sequence_folder = '/Users/user/desktop/output/test/sequence/'
|
290
|
+
# can only be run after the name_parser and parent_path
|
291
|
+
def sequence_folder
|
292
|
+
"#{@parent_path}output/#{@input_name}/sequence/"
|
293
|
+
end
|
294
|
+
|
295
|
+
##
|
296
|
+
# creates an instance variable with the full path of the output
|
297
|
+
# example: output_path => @sequence_frame_path = '/Users/user/desktop/output/test/sequence/test.png'
|
298
|
+
# can only be run after the name_parser and parent_path
|
299
|
+
def sequence_frame_path
|
300
|
+
"#{@parent_path}output/#{@input_name}/sequence/#{@input_name}.png"
|
301
|
+
end
|
302
|
+
|
303
|
+
##
|
304
|
+
# creates an instance variable with the image path, used when a glitch sequence is created but
|
305
|
+
# the original image is not need in said sequence
|
306
|
+
# example: image_path => @image_path = '/Users/user/desktop/output/test/test.png'
|
307
|
+
# can only be run after the name_parser and parent_path
|
308
|
+
def image_path
|
309
|
+
"#{@parent_path}output/#{@input_name}/#{@input_name}.png"
|
310
|
+
end
|
311
|
+
|
312
|
+
##
|
313
|
+
# creates directory using @sequence_folder for the output for either the glitch_sequence or barrage methods
|
314
|
+
def make_dir?
|
315
|
+
FileUtils.mkdir_p(@sequence_folder) unless Dir.exist?(@sequence_folder)
|
316
|
+
end
|
317
|
+
|
318
|
+
def path_selector(counter, compress, input)
|
319
|
+
if compress
|
320
|
+
if counter > 1
|
321
|
+
@path = @image_path
|
322
|
+
else
|
323
|
+
@path = @sequence_frame_path
|
324
|
+
end
|
325
|
+
else
|
326
|
+
@path = input
|
327
|
+
FileUtils.copy(input, @sequence_frame_path)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
##
|
332
|
+
# still being used but partially deprecated
|
333
|
+
def output(base_uri, input_name, output_name, options, gif, output_folder)
|
334
|
+
base_uri = base_uri + 'output/'
|
335
|
+
if gif
|
336
|
+
else
|
337
|
+
Dir.mkdir(base_uri) unless Dir.exist?(base_uri)
|
338
|
+
end
|
339
|
+
|
340
|
+
if output_name.nil?
|
341
|
+
rando = '_' + (0...4).map { 65.+(rand(26)).chr }.join.downcase
|
342
|
+
settings_file = File.new(base_uri + input_name + rando + '.txt', 'w')
|
343
|
+
settings_file.puts(options.to_s)
|
344
|
+
settings_file.close
|
345
|
+
base_uri + input_name + rando + '.png'
|
346
|
+
elsif gif || output_folder
|
347
|
+
@base_uri = base_uri + "#{input_name}/"
|
348
|
+
# needs to be refactored to create an output folder instead of a sequence folder
|
349
|
+
FileUtils.mkdir_p(@sequence_folder) unless Dir.exist?(@sequence_folder)
|
350
|
+
settings_file = File.new(@sequence_folder + output_name + '.txt', 'w')
|
351
|
+
settings_file.puts(options.to_s)
|
352
|
+
settings_file.close
|
353
|
+
@sequence_folder + output_name + '.png'
|
354
|
+
elsif !gif && !output_folder
|
355
|
+
settings_file = File.new(base_uri + output_name + '.txt', 'w')
|
356
|
+
settings_file.puts(options.to_s)
|
357
|
+
settings_file.close
|
358
|
+
base_uri + output_name + '.png'
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
def file_name_with_settings(input_uri, options, output_name, gif, output_folder)
|
363
|
+
base_uri = input_uri.dup
|
364
|
+
input_name = File.basename(base_uri, '.png')
|
365
|
+
length = input_name.length + 4
|
366
|
+
uri_length = base_uri.length
|
367
|
+
start = uri_length - length
|
368
|
+
base_uri[start..uri_length] = ''
|
369
|
+
if output_name.nil?
|
370
|
+
output(base_uri, input_name, nil, options, gif, output_folder)
|
371
|
+
else
|
372
|
+
output(base_uri, input_name, output_name, options, gif, output_folder)
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
##
|
377
|
+
# does not work needs to be recreated
|
378
|
+
# def convert(img)
|
379
|
+
# image = ImageList.new(img)
|
380
|
+
# image.write("#{@parent_path}#{@input_name}.png") { self.quality = 10 }
|
381
|
+
# data = File.open("#{@parent_path}#{@input_name}.png", 'rb').read(9)
|
382
|
+
# File.write(f = "#{@parent_path}#{@input_name}.png", File.read(f).gsub(/#{data}/,"\x89PNG\r\n\x1A\n"))
|
383
|
+
# end
|
384
|
+
end
|
385
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'pixel_dreamer/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "pixel_dreamer"
|
8
|
+
spec.version = PixelDreamer::VERSION
|
9
|
+
spec.authors = ["Christian Samuel"]
|
10
|
+
spec.email = ["christian.leumas@icloud.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{A wrapper for pxlsrt, adds settings and gif creation.}
|
13
|
+
spec.description = %q{Create pixel sorted gifs.}
|
14
|
+
spec.homepage = "https://github.com/13um45/pixel_dreamer"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_runtime_dependency 'rmagick', '~> 2.16.0'
|
25
|
+
spec.add_runtime_dependency 'pxlsrt', '~> 1.8.2'
|
26
|
+
spec.add_runtime_dependency 'image_optim', '~> 0.24.0'
|
27
|
+
spec.add_runtime_dependency 'image_optim_pack', '~> 0.3.0.20161108'
|
28
|
+
|
29
|
+
spec.add_development_dependency 'bundler', '~> 1.13'
|
30
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
31
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
32
|
+
spec.add_development_dependency 'simplecov', '~> 0.12.0'
|
33
|
+
end
|
data/support/test.png
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pixel_dreamer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Christian Samuel
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-04-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rmagick
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.16.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.16.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pxlsrt
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.8.2
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.8.2
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: image_optim
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.24.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.24.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: image_optim_pack
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.3.0.20161108
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.3.0.20161108
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.13'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.13'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '10.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '10.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: simplecov
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.12.0
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.12.0
|
125
|
+
description: Create pixel sorted gifs.
|
126
|
+
email:
|
127
|
+
- christian.leumas@icloud.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".gitignore"
|
133
|
+
- ".rspec"
|
134
|
+
- ".travis.yml"
|
135
|
+
- Gemfile
|
136
|
+
- LICENSE.txt
|
137
|
+
- README.md
|
138
|
+
- Rakefile
|
139
|
+
- bin/console
|
140
|
+
- bin/setup
|
141
|
+
- lib/pixel_dreamer.rb
|
142
|
+
- lib/pixel_dreamer/constants.rb
|
143
|
+
- lib/pixel_dreamer/version.rb
|
144
|
+
- pixel_dreamer.gemspec
|
145
|
+
- support/test.png
|
146
|
+
homepage: https://github.com/13um45/pixel_dreamer
|
147
|
+
licenses:
|
148
|
+
- MIT
|
149
|
+
metadata: {}
|
150
|
+
post_install_message:
|
151
|
+
rdoc_options: []
|
152
|
+
require_paths:
|
153
|
+
- lib
|
154
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
161
|
+
- - ">="
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '0'
|
164
|
+
requirements: []
|
165
|
+
rubyforge_project:
|
166
|
+
rubygems_version: 2.4.5.1
|
167
|
+
signing_key:
|
168
|
+
specification_version: 4
|
169
|
+
summary: A wrapper for pxlsrt, adds settings and gif creation.
|
170
|
+
test_files: []
|