vcs_ruby 0.8.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|