forked from afeld/mustachio
/
shortcuts.rb
81 lines (68 loc) · 2.56 KB
/
shortcuts.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
require 'face'
Magickly.dragonfly.configure do |c|
c.log_commands = true
c.analyser.add :face_data do |temp_object|
Mustachio.face_client.faces_detect(:file => temp_object.file, :attributes => 'none')['photos'].first
end
c.analyser.add :face_data_as_px do |temp_object|
data = Mustachio.face_client.faces_detect(:file => temp_object.file, :attributes => 'none')['photos'].first # TODO use #face_data
new_tags = []
data['tags'].map do |face|
has_all_attrs = Mustachio::FACE_POS_ATTRS.all? do |pos_attr|
if face[pos_attr]
face[pos_attr]['x'] *= (data['width'] / 100.0)
face[pos_attr]['y'] *= (data['height'] / 100.0)
true
else
# face attribute missing
false
end
end
new_tags << face if has_all_attrs
end
data['tags'] = new_tags
data
end
c.job :mustachify do |stache_num_param|
photo_data = @job.face_data_as_px
width = photo_data['width']
commands = ['-virtual-pixel transparent']
photo_data['tags'].each do |face|
stache_num = case stache_num_param
when true
0
when 'true'
0
when 'rand'
rand(Mustachio.mustaches.size)
else
stache_num_param.to_i
end
mustache = Mustachio.mustaches[stache_num]
# perform transform such that the mustache is the height
# of the upper lip, and the bottom-center of the stache
# is mapped to the center of the mouth
rotation = Math.atan(
( face['mouth_right']['y'] - face['mouth_left']['y'] ).to_f /
( face['mouth_right']['x'] - face['mouth_left']['x'] ).to_f
) / Math::PI * 180.0
desired_height = Math.sqrt(
( face['nose']['x'] - face['mouth_center']['x'] ).to_f**2 +
( face['nose']['y'] - face['mouth_center']['y'] ).to_f**2
)
mouth_intersect = mustache['height'] - mustache['mouth_overlap']
scale = desired_height / mouth_intersect
srt_params = [
[ mustache['width'] / 2.0, mouth_intersect - mustache['vert_offset'] ].map{|e| e.to_i }.join(','), # bottom-center of stache
scale, # scale
rotation, # rotate
[ face['mouth_center']['x'], face['mouth_center']['y'] ].map{|e| e.to_i }.join(',') # middle of mouth
]
srt_params_str = srt_params.join(' ')
commands << "\\( #{mustache['file_path']} +distort SRT '#{srt_params_str}' \\)"
end
commands << "-flatten"
command_str = commands.join(' ')
process :convert, command_str
end
end