vcs_ruby 0.8.5 → 1.0.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.
- data/bin/vcs.rb +13 -0
- data/lib/black.yml +12 -0
- data/lib/capturer.rb +23 -7
- data/lib/command.rb +4 -2
- data/lib/configuration.rb +42 -6
- data/lib/contact_sheet.rb +37 -8
- data/lib/defaults.yml +4 -0
- data/lib/ffmpeg.rb +30 -0
- data/lib/font.rb +2 -2
- data/lib/libav.rb +32 -1
- data/lib/mplayer.rb +97 -1
- data/lib/oldstyle.yml +12 -0
- data/lib/thumbnail.rb +26 -11
- data/lib/tools.rb +7 -1
- data/lib/version.info +1 -1
- data/lib/white.yml +12 -0
- metadata +5 -2
data/bin/vcs.rb
CHANGED
@@ -89,6 +89,18 @@ optparse = OptionParser.new do|opts|
|
|
89
89
|
opts.on( '-l [HIGHLIGHT]', '--highlight [HIGHLIGHT]' 'Add the frame found at timestamp [HIGHLIGHT] as a highlight.') do |highlight|
|
90
90
|
options[:highlight] = TimeIndex.new highlight
|
91
91
|
end
|
92
|
+
opts.on("--[no-]timestamp", "Add timestamp to thumbnails. Default: true") do |timestamp|
|
93
|
+
options[:timestamp] = timestamp
|
94
|
+
end
|
95
|
+
opts.on("--[no-]shadow", "Add shadow to thumbnails. Default: true") do |shadow|
|
96
|
+
options[:shadow] = shadow
|
97
|
+
end
|
98
|
+
opts.on("--[no-]polaroid", "Thumbnails look as polaroid frames. Default: false") do |polaroid|
|
99
|
+
options[:polaroid] = polaroid
|
100
|
+
end
|
101
|
+
opts.on( '-p [PROFILE]', '--profile [PROFILE]' 'Loads additional setting from profile.yml.') do |profile|
|
102
|
+
options[:profile] = profile
|
103
|
+
end
|
92
104
|
opts.on( '-q', '--quiet', 'Don\'t print progress messages just errors. Repeat to mute completely, even on error.') do |file|
|
93
105
|
options[:quiet] = true
|
94
106
|
end
|
@@ -139,5 +151,6 @@ begin
|
|
139
151
|
end
|
140
152
|
rescue Exception => e
|
141
153
|
STDERR.puts "ERROR: #{e.message}"
|
154
|
+
STDERR.puts "#{e.backtrace.join("\n")}" if options[:verbose]
|
142
155
|
end
|
143
156
|
|
data/lib/black.yml
ADDED
data/lib/capturer.rb
CHANGED
@@ -9,27 +9,43 @@ module VCSRuby
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def name
|
12
|
-
raise "
|
12
|
+
raise "NotImplementedException"
|
13
13
|
end
|
14
14
|
|
15
15
|
def load_video
|
16
|
-
raise "
|
16
|
+
raise "NotImplementedException"
|
17
17
|
end
|
18
18
|
|
19
19
|
def length
|
20
|
-
raise "
|
20
|
+
raise "NotImplementedException"
|
21
21
|
end
|
22
22
|
|
23
23
|
def width
|
24
|
-
raise "
|
24
|
+
raise "NotImplementedException"
|
25
25
|
end
|
26
26
|
|
27
27
|
def height
|
28
|
-
raise "
|
28
|
+
raise "NotImplementedException"
|
29
29
|
end
|
30
30
|
|
31
|
-
def grab time
|
32
|
-
raise "
|
31
|
+
def grab time, image_path
|
32
|
+
raise "NotImplementedException"
|
33
|
+
end
|
34
|
+
|
35
|
+
def available_formats
|
36
|
+
raise "NotImplementedException"
|
37
|
+
end
|
38
|
+
|
39
|
+
def format
|
40
|
+
@format
|
41
|
+
end
|
42
|
+
|
43
|
+
def format= format
|
44
|
+
if available_formats.include? format
|
45
|
+
@format = format
|
46
|
+
else
|
47
|
+
raise "Capturer '#{name}' does not support format: '#{format}'"
|
48
|
+
end
|
33
49
|
end
|
34
50
|
end
|
35
51
|
end
|
data/lib/command.rb
CHANGED
@@ -15,8 +15,9 @@ module VCSRuby
|
|
15
15
|
@available
|
16
16
|
end
|
17
17
|
|
18
|
-
def execute parameter, streams = 0
|
18
|
+
def execute parameter, streams = 0, no_error = false
|
19
19
|
raise "Command '#{name}' not available" unless available?
|
20
|
+
puts "#{@command} #{parameter} #{streams}" if Tools.verbose?
|
20
21
|
result = nil
|
21
22
|
if Tools::windows?
|
22
23
|
streams = '2> nul' if streams === 0
|
@@ -28,9 +29,10 @@ module VCSRuby
|
|
28
29
|
result =`#{@command} #{parameter} #{streams}`
|
29
30
|
end
|
30
31
|
|
31
|
-
raise "#{@command} failed with return value '#{$?}'"unless
|
32
|
+
raise "#{@command} failed with return value '#{$?}'" unless $?.to_i == 0 || no_error
|
32
33
|
return result
|
33
34
|
end
|
35
|
+
|
34
36
|
private
|
35
37
|
# http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
|
36
38
|
def which cmd
|
data/lib/configuration.rb
CHANGED
@@ -4,30 +4,54 @@
|
|
4
4
|
|
5
5
|
require 'font'
|
6
6
|
|
7
|
+
|
8
|
+
class ::Hash
|
9
|
+
def deep_merge(second)
|
10
|
+
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
|
11
|
+
self.merge(second, &merger)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
7
15
|
module VCSRuby
|
8
16
|
class Configuration
|
9
17
|
attr_accessor :capturer
|
10
18
|
attr_reader :header_font, :title_font, :timestamp_font, :signature_font
|
11
19
|
|
12
|
-
def initialize
|
20
|
+
def initialize profile
|
13
21
|
default_config_file = File.expand_path("defaults.yml", File.dirname(__FILE__))
|
14
|
-
|
22
|
+
@config = ::YAML::load_file(default_config_file)
|
15
23
|
|
16
|
-
|
24
|
+
local_config_files = ['~/.vcs.rb.yml']
|
17
25
|
local_config_files.select{ |f| File.exists?(f) }.each do |local_config_file|
|
18
26
|
puts "Local configuration file loaded: #{local_config_file}" if Tools.verbose?
|
19
27
|
local_config = YAML::load_file(local_config_file)
|
20
|
-
|
28
|
+
@config = @config.deep_merge(local_config)
|
21
29
|
end
|
22
30
|
|
23
|
-
|
24
|
-
|
31
|
+
load_profile profile if profile
|
32
|
+
|
25
33
|
@header_font = Font.new @config['style']['header']['font'], @config['style']['header']['size']
|
26
34
|
@title_font = Font.new @config['style']['title']['font'], @config['style']['title']['size']
|
27
35
|
@timestamp_font = Font.new @config['style']['timestamp']['font'], @config['style']['timestamp']['size']
|
28
36
|
@signature_font = Font.new @config['style']['signature']['font'], @config['style']['signature']['size']
|
29
37
|
end
|
30
38
|
|
39
|
+
def load_profile profile
|
40
|
+
profiles = [File.expand_path("#{profile}.yml", File.dirname(__FILE__)), "~/#{profile}.yml"]
|
41
|
+
|
42
|
+
found = false
|
43
|
+
profiles.each do |profile|
|
44
|
+
if File.exists?(profile)
|
45
|
+
puts "Profile loaded: #{profile}" if Tools.verbose?
|
46
|
+
config = YAML::load_file(profile)
|
47
|
+
@config = @config.deep_merge(config)
|
48
|
+
found = true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
raise "No profile '#{profile}' found" unless found
|
53
|
+
end
|
54
|
+
|
31
55
|
def rows
|
32
56
|
@config['main']['rows'] ? @config['main']['rows'].to_i : nil
|
33
57
|
end
|
@@ -99,5 +123,17 @@ module VCSRuby
|
|
99
123
|
def blank_alternatives
|
100
124
|
@config['lowlevel']['blank_alternatives'].map{ |e| TimeIndex.new e.to_i }
|
101
125
|
end
|
126
|
+
|
127
|
+
def timestamp
|
128
|
+
!!@config['filter']['timestamp']
|
129
|
+
end
|
130
|
+
|
131
|
+
def polaroid
|
132
|
+
!!@config['filter']['polaroid']
|
133
|
+
end
|
134
|
+
|
135
|
+
def softshadow
|
136
|
+
!!@config['filter']['softshadow']
|
137
|
+
end
|
102
138
|
end
|
103
139
|
end
|
data/lib/contact_sheet.rb
CHANGED
@@ -11,12 +11,13 @@ require 'vcs'
|
|
11
11
|
module VCSRuby
|
12
12
|
class ContactSheet
|
13
13
|
attr_accessor :capturer, :format, :signature, :title, :highlight
|
14
|
+
attr_accessor :softshadow, :timestamp, :polaroid
|
14
15
|
attr_reader :thumbnail_width, :thumbnail_height
|
15
16
|
attr_reader :length, :from, :to
|
16
17
|
|
17
|
-
def initialize video,
|
18
|
-
@capturer =
|
19
|
-
@configuration = Configuration.new
|
18
|
+
def initialize video, profile = nil
|
19
|
+
@capturer = :any
|
20
|
+
@configuration = Configuration.new profile
|
20
21
|
@signature = "Created by Video Contact Sheet Ruby"
|
21
22
|
initialize_capturers video
|
22
23
|
initialize_filename(File.basename(@video, '.*'))
|
@@ -24,6 +25,11 @@ module VCSRuby
|
|
24
25
|
detect_video_properties
|
25
26
|
|
26
27
|
@thumbnails = []
|
28
|
+
@filters = []
|
29
|
+
|
30
|
+
@timestamp = @configuration.timestamp
|
31
|
+
@softshadow = @configuration.softshadow
|
32
|
+
@polaroid = @configuration.polaroid
|
27
33
|
|
28
34
|
@tempdir = Dir.mktmpdir
|
29
35
|
|
@@ -115,13 +121,15 @@ module VCSRuby
|
|
115
121
|
end
|
116
122
|
|
117
123
|
def build
|
124
|
+
selected_capturer.format = selected_capturer.available_formats.first
|
125
|
+
initialize_filters
|
118
126
|
initialize_thumbnails
|
119
127
|
capture_thumbnails
|
120
128
|
|
121
129
|
puts "Composing standard contact sheet..." unless Tools.quiet?
|
122
|
-
|
130
|
+
montage = splice_montage(montage_thumbs)
|
123
131
|
|
124
|
-
image = MiniMagick::Image.open(
|
132
|
+
image = MiniMagick::Image.open(montage)
|
125
133
|
|
126
134
|
puts "Adding header and footer..." unless Tools.quiet?
|
127
135
|
final = add_header_and_footer image
|
@@ -158,6 +166,13 @@ private
|
|
158
166
|
@capturers.select{ |c| c.available? }
|
159
167
|
end
|
160
168
|
|
169
|
+
def initialize_filters
|
170
|
+
@filters << :resize_filter
|
171
|
+
@filters << :softshadow_filter if softshadow
|
172
|
+
@filters << :timestamp_filter if timestamp
|
173
|
+
@filters << :polaroid_filter if polaroid
|
174
|
+
end
|
175
|
+
|
161
176
|
def initialize_thumbnails
|
162
177
|
time = @from
|
163
178
|
(1..number_of_caps).each do |i|
|
@@ -166,7 +181,8 @@ private
|
|
166
181
|
thumb.width = thumbnail_width
|
167
182
|
thumb.height = thumbnail_height
|
168
183
|
thumb.time = (time += interval)
|
169
|
-
thumb.image_path = File::join(@tempdir, "th#{"%03d" % i}.
|
184
|
+
thumb.image_path = File::join(@tempdir, "th#{"%03d" % i}.#{selected_capturer.format.to_s}")
|
185
|
+
thumb.filters.push(*@filters)
|
170
186
|
|
171
187
|
@thumbnails << thumb
|
172
188
|
end
|
@@ -219,11 +235,24 @@ private
|
|
219
235
|
end
|
220
236
|
|
221
237
|
def splice_montage montage_path
|
238
|
+
if softshadow
|
239
|
+
left = @configuration.padding + 3
|
240
|
+
top = @configuration.padding + 5
|
241
|
+
bottom = right = @configuration.padding
|
242
|
+
else
|
243
|
+
left = right = top = bottom = @configuration.padding
|
244
|
+
end
|
245
|
+
|
246
|
+
|
222
247
|
file_path = File::join(@tempdir, 'spliced.png')
|
223
248
|
MiniMagick::Tool::Convert.new do |convert|
|
224
249
|
convert << montage_path
|
225
250
|
convert.background @configuration.contact_background
|
226
|
-
|
251
|
+
|
252
|
+
convert.splice "#{left}x#{top}"
|
253
|
+
convert.gravity 'SouthEast'
|
254
|
+
convert.splice "#{right}x#{bottom}"
|
255
|
+
|
227
256
|
convert << file_path
|
228
257
|
end
|
229
258
|
file_path
|
@@ -295,7 +324,7 @@ private
|
|
295
324
|
end
|
296
325
|
a.pointsize @configuration.header_font.size
|
297
326
|
a.background @configuration.header_background
|
298
|
-
a.fill
|
327
|
+
a.fill @configuration.header_color
|
299
328
|
a.stack do |b|
|
300
329
|
b.gravity 'West'
|
301
330
|
b.stack do |c|
|
data/lib/defaults.yml
CHANGED
data/lib/ffmpeg.rb
CHANGED
@@ -13,6 +13,12 @@ module VCSRuby
|
|
13
13
|
DIMENSION = 5
|
14
14
|
FPS = 7
|
15
15
|
|
16
|
+
HEADER = 10
|
17
|
+
|
18
|
+
ENCODING_SUPPORT = 2
|
19
|
+
VIDEO_CODEC = 3
|
20
|
+
NAME = 8
|
21
|
+
|
16
22
|
def initialize video
|
17
23
|
@video = video
|
18
24
|
@ffmpeg = Command.new :ffmpeg, 'ffmpeg'
|
@@ -90,6 +96,30 @@ module VCSRuby
|
|
90
96
|
@ffmpeg.execute "-y -ss #{time.total_seconds} -i \"#{@video}\" -an -dframes 1 -vframes 1 -vcodec png -f rawvideo \"#{image_path}\""
|
91
97
|
end
|
92
98
|
|
99
|
+
def available_formats
|
100
|
+
# Ordered by priority
|
101
|
+
image_formats = ['png', 'tiff', 'bmp', 'mjpeg']
|
102
|
+
formats = []
|
103
|
+
|
104
|
+
list = @ffprobe.execute "-codecs"
|
105
|
+
list.lines.drop(HEADER).each do |codec|
|
106
|
+
name, e, v = format_split(codec)
|
107
|
+
formats << name if image_formats.include?(name) && e && v
|
108
|
+
end
|
109
|
+
|
110
|
+
image_formats.select{ |format| formats.include?(format) }.map(&:to_sym)
|
111
|
+
end
|
112
|
+
|
113
|
+
def format_split line
|
114
|
+
e = line[ENCODING_SUPPORT] == 'E'
|
115
|
+
v = line[VIDEO_CODEC] == 'V'
|
116
|
+
|
117
|
+
name = line[NAME..-1].split(' ', 2).first
|
118
|
+
return name, e, v
|
119
|
+
rescue
|
120
|
+
return nil, false, false
|
121
|
+
end
|
122
|
+
|
93
123
|
def to_s
|
94
124
|
"FFmpeg #{@version}"
|
95
125
|
end
|
data/lib/font.rb
CHANGED
@@ -58,12 +58,12 @@ module VCSRuby
|
|
58
58
|
fonts.lines.each do |line|
|
59
59
|
key, value = line.strip.split(':', 2).map(&:strip)
|
60
60
|
|
61
|
-
next if ['Path'].include? key
|
61
|
+
next if [nil, 'Path'].include? key
|
62
62
|
|
63
63
|
if key == 'Font'
|
64
64
|
@@fonts[value] = font = IMFont.new(value)
|
65
65
|
else
|
66
|
-
font.send(key
|
66
|
+
font.send("#{key}=", value)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
data/lib/libav.rb
CHANGED
@@ -13,6 +13,12 @@ module VCSRuby
|
|
13
13
|
DIMENSION = 4
|
14
14
|
FPS = 6
|
15
15
|
|
16
|
+
HEADER = 10
|
17
|
+
|
18
|
+
ENCODING_SUPPORT = 2
|
19
|
+
VIDEO_CODEC = 3
|
20
|
+
NAME = 8
|
21
|
+
|
16
22
|
def initialize video
|
17
23
|
@video = video
|
18
24
|
@avconv = Command.new :libav, 'avconv'
|
@@ -29,6 +35,7 @@ module VCSRuby
|
|
29
35
|
@avconv.available? && @avprobe.available?
|
30
36
|
end
|
31
37
|
|
38
|
+
|
32
39
|
def detect_version
|
33
40
|
info = @avconv.execute('-version')
|
34
41
|
match = /avconv ([\d|.|-|:]*)/.match(info)
|
@@ -79,7 +86,31 @@ module VCSRuby
|
|
79
86
|
end
|
80
87
|
|
81
88
|
def grab time, image_path
|
82
|
-
@avconv.execute "-y -ss #{time.total_seconds} -i \"#{@video}\" -an -dframes 1 -vframes 1 -vcodec
|
89
|
+
@avconv.execute "-y -ss #{time.total_seconds} -i \"#{@video}\" -an -dframes 1 -vframes 1 -vcodec #{format} -f rawvideo \"#{image_path}\""
|
90
|
+
end
|
91
|
+
|
92
|
+
def available_formats
|
93
|
+
# Ordered by priority
|
94
|
+
image_formats = ['png', 'tiff', 'bmp', 'mjpeg']
|
95
|
+
formats = []
|
96
|
+
|
97
|
+
list = @avprobe.execute "-codecs"
|
98
|
+
list.lines.drop(HEADER).each do |codec|
|
99
|
+
name, e, v = format_split(codec)
|
100
|
+
formats << name if image_formats.include?(name) && e && v
|
101
|
+
end
|
102
|
+
|
103
|
+
image_formats.select{ |format| formats.include?(format) }.map(&:to_sym)
|
104
|
+
end
|
105
|
+
|
106
|
+
def format_split line
|
107
|
+
e = line[ENCODING_SUPPORT] == 'E'
|
108
|
+
v = line[VIDEO_CODEC] == 'V'
|
109
|
+
|
110
|
+
name = line[NAME..-1].split(' ', 2).first
|
111
|
+
return name, e, v
|
112
|
+
rescue
|
113
|
+
return nil, false, false
|
83
114
|
end
|
84
115
|
|
85
116
|
def to_s
|
data/lib/mplayer.rb
CHANGED
@@ -4,12 +4,18 @@
|
|
4
4
|
|
5
5
|
require 'command'
|
6
6
|
require 'capturer'
|
7
|
+
require 'fileutils'
|
7
8
|
|
8
9
|
module VCSRuby
|
9
10
|
class MPlayer < Capturer
|
11
|
+
|
12
|
+
HEADER = 2
|
13
|
+
|
10
14
|
def initialize video
|
11
15
|
@video = video
|
12
16
|
@mplayer = Command.new :mplayer, 'mplayer'
|
17
|
+
|
18
|
+
detect_version if available?
|
13
19
|
end
|
14
20
|
|
15
21
|
def name
|
@@ -17,12 +23,102 @@ module VCSRuby
|
|
17
23
|
end
|
18
24
|
|
19
25
|
def available?
|
20
|
-
@mplayer.available?
|
26
|
+
@mplayer.available?
|
21
27
|
end
|
22
28
|
|
29
|
+
def detect_version
|
30
|
+
info = @mplayer.execute('')
|
31
|
+
match = /MPlayer (.*),/.match(info)
|
32
|
+
@version = match[1] if match
|
33
|
+
end
|
34
|
+
|
35
|
+
def length
|
36
|
+
load_probe
|
37
|
+
@length
|
38
|
+
end
|
39
|
+
|
40
|
+
def width
|
41
|
+
load_probe
|
42
|
+
@width
|
43
|
+
end
|
44
|
+
|
45
|
+
def height
|
46
|
+
load_probe
|
47
|
+
@height
|
48
|
+
end
|
49
|
+
|
50
|
+
def video_codec
|
51
|
+
load_probe
|
52
|
+
@video_codec
|
53
|
+
end
|
54
|
+
|
55
|
+
def audio_codec
|
56
|
+
load_probe
|
57
|
+
@audio_codec
|
58
|
+
end
|
59
|
+
|
60
|
+
def fps
|
61
|
+
load_probe
|
62
|
+
@fps
|
63
|
+
end
|
64
|
+
|
65
|
+
def file_pattern n
|
66
|
+
if format == :jpeg
|
67
|
+
"#{"%08d" % n}.jpg"
|
68
|
+
else
|
69
|
+
"#{"%08d" % n}.#{format.to_s}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def grab time, image_path
|
74
|
+
@mplayer.execute "-sws 9 -ao null -benchmark -vo #{@format} -quiet -frames 5 -ss #{time.total_seconds} \"#{@video}\""
|
75
|
+
(1..4).each { |n| FileUtils.rm(file_pattern(n)) }
|
76
|
+
FileUtils.mv(file_pattern(5), image_path)
|
77
|
+
end
|
78
|
+
|
79
|
+
def available_formats
|
80
|
+
# Ordered by priority
|
81
|
+
image_formats = ['png', 'jpeg']
|
82
|
+
formats = []
|
83
|
+
|
84
|
+
list = @mplayer.execute("-vo help", 0, true)
|
85
|
+
list.lines.drop(HEADER).each do |codec|
|
86
|
+
name = format_split(codec)
|
87
|
+
formats << name if image_formats.include?(name)
|
88
|
+
end
|
89
|
+
|
90
|
+
image_formats.select{ |format| formats.include?(format) }.map(&:to_sym)
|
91
|
+
end
|
92
|
+
|
93
|
+
def format_split line
|
94
|
+
name = line.strip.split(' ', 2).first
|
95
|
+
end
|
96
|
+
|
23
97
|
def to_s
|
24
98
|
"MPlayer #{@version}"
|
25
99
|
end
|
100
|
+
private
|
101
|
+
def parsed?
|
102
|
+
!!@parsed
|
103
|
+
end
|
26
104
|
|
105
|
+
def load_probe
|
106
|
+
unless parsed?
|
107
|
+
parse_identify(@mplayer.execute("-ao null -vo null -identify -frames 0 -quiet \"#{@video}\""))
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def parse_identify info
|
112
|
+
info.lines.each do |line|
|
113
|
+
key, value = line.split('=', 2)
|
114
|
+
@length = TimeIndex.new value.to_f if key == 'ID_LENGTH'
|
115
|
+
@width = value.to_i if key == 'ID_VIDEO_WIDTH'
|
116
|
+
@height = value.to_i if key == 'ID_VIDEO_HEIGHT'
|
117
|
+
@video_codec = value.chomp if key == 'ID_VIDEO_FORMAT'
|
118
|
+
@audio_codec = value.chomp if key == 'ID_AUDIO_FORMAT'
|
119
|
+
@fps = value.to_f if key == 'ID_VIDEO_FPS'
|
120
|
+
end
|
121
|
+
@parsed = true
|
122
|
+
end
|
27
123
|
end
|
28
124
|
end
|
data/lib/oldstyle.yml
ADDED
data/lib/thumbnail.rb
CHANGED
@@ -9,12 +9,13 @@ module VCSRuby
|
|
9
9
|
attr_accessor :width, :height, :aspect
|
10
10
|
attr_accessor :image_path
|
11
11
|
attr_accessor :time
|
12
|
+
attr_reader :filters
|
12
13
|
|
13
14
|
def initialize capper, video, configuration
|
14
15
|
@capper = capper
|
15
16
|
@video = video
|
16
17
|
@configuration = configuration
|
17
|
-
@filters = [
|
18
|
+
@filters = []
|
18
19
|
end
|
19
20
|
|
20
21
|
def capture
|
@@ -47,14 +48,28 @@ module VCSRuby
|
|
47
48
|
convert.background 'Transparent'
|
48
49
|
convert.fill 'Transparent'
|
49
50
|
convert << @image_path
|
50
|
-
|
51
|
-
|
51
|
+
|
52
|
+
sorted_filters.each do |filter|
|
53
|
+
call_filter filter, convert
|
52
54
|
end
|
55
|
+
|
53
56
|
convert << @image_path
|
54
57
|
end
|
55
58
|
end
|
56
59
|
|
57
60
|
private
|
61
|
+
def call_filter filter, convert
|
62
|
+
if respond_to?(filter, true)
|
63
|
+
method(filter).call(convert)
|
64
|
+
else
|
65
|
+
raise "Filter '#{filter}' does not exist"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def sorted_filters
|
70
|
+
[:resize_filter, :timestamp_filter, :photoframe_filter, :polaroid_filter, :random_rotation_filter, :softshadow_filter].select{ |filter| @filters.include?(filter) }
|
71
|
+
end
|
72
|
+
|
58
73
|
def resize_filter convert
|
59
74
|
convert.resize "#{width}x#{height}!"
|
60
75
|
end
|
@@ -74,13 +89,6 @@ private
|
|
74
89
|
convert.gravity 'None'
|
75
90
|
end
|
76
91
|
|
77
|
-
def photoframe_filter convert
|
78
|
-
convert.bordercolor 'White'
|
79
|
-
convert.border 3
|
80
|
-
convert.bordercolor 'Grey60'
|
81
|
-
convert.border 1
|
82
|
-
end
|
83
|
-
|
84
92
|
def softshadow_filter convert
|
85
93
|
convert.stack do |box|
|
86
94
|
box.background 'Black'
|
@@ -94,6 +102,13 @@ private
|
|
94
102
|
convert.repage.+
|
95
103
|
end
|
96
104
|
|
105
|
+
def photoframe_filter convert
|
106
|
+
convert.bordercolor 'White'
|
107
|
+
convert.border 3
|
108
|
+
convert.bordercolor 'Grey60'
|
109
|
+
convert.border 1
|
110
|
+
end
|
111
|
+
|
97
112
|
def polaroid_filter convert
|
98
113
|
border = 8
|
99
114
|
convert.stack do |a|
|
@@ -109,8 +124,8 @@ private
|
|
109
124
|
a.flip
|
110
125
|
a.bordercolor 'Grey60'
|
111
126
|
a.border 1
|
112
|
-
a.repage.+
|
113
127
|
end
|
128
|
+
convert.repage.+
|
114
129
|
end
|
115
130
|
|
116
131
|
def random_rotation_filter convert
|
data/lib/tools.rb
CHANGED
@@ -40,7 +40,9 @@ module VCSRuby
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def self.contact_sheet_with_options video, options
|
43
|
-
sheet = VCSRuby::ContactSheet.new video, options[:
|
43
|
+
sheet = VCSRuby::ContactSheet.new video, options[:profile]
|
44
|
+
|
45
|
+
sheet.capturer = options[:capturer]
|
44
46
|
sheet.format = options[:format] if options[:format]
|
45
47
|
sheet.title = options[:title] if options[:title]
|
46
48
|
sheet.signature = options[:signature] if options[:signature]
|
@@ -56,6 +58,10 @@ module VCSRuby
|
|
56
58
|
sheet.to = options[:to] if options[:to]
|
57
59
|
sheet.highlight = options[:highlight] if options[:highlight]
|
58
60
|
|
61
|
+
sheet.timestamps = options[:timestamps] if options[:timestamps] != nil
|
62
|
+
sheet.softshadow = options[:softshadow] if options[:softshadow] != nil
|
63
|
+
sheet.polaroid = options[:polaroid] if options[:polaroid] != nil
|
64
|
+
|
59
65
|
return sheet
|
60
66
|
end
|
61
67
|
|
data/lib/version.info
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.1
|
data/lib/white.yml
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vcs_ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-05-
|
12
|
+
date: 2016-05-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mini_magick
|
@@ -77,11 +77,14 @@ files:
|
|
77
77
|
- lib/ffmpeg.rb
|
78
78
|
- lib/version.rb
|
79
79
|
- lib/libav.rb
|
80
|
+
- lib/white.yml
|
80
81
|
- lib/capturer.rb
|
81
82
|
- lib/version.info
|
82
83
|
- lib/vcs.rb
|
83
84
|
- lib/command.rb
|
85
|
+
- lib/black.yml
|
84
86
|
- lib/configuration.rb
|
87
|
+
- lib/oldstyle.yml
|
85
88
|
- lib/defaults.yml
|
86
89
|
- bin/vcs.rb
|
87
90
|
homepage: https://github.com/FreeApophis/vcs.rb
|