yamg 0.0.5 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +76 -13
- data/bin/yamg +1 -6
- data/lib/yamg/cli.rb +79 -0
- data/lib/yamg/icon.rb +77 -0
- data/lib/yamg/screenshot.rb +35 -0
- data/lib/yamg/splash.rb +58 -0
- data/lib/yamg/templates.yaml +197 -0
- data/lib/yamg/version.rb +1 -1
- data/lib/yamg/yamg.yml +61 -0
- data/lib/yamg.rb +45 -379
- data/spec/spec_helper.rb +17 -0
- data/spec/yamg/yamg_spec.rb +28 -0
- data/yamg.gemspec +1 -0
- metadata +27 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f878b0990d8eaae671edba9ac0a0838d8af4ca4
|
4
|
+
data.tar.gz: 5ad0cdcd21efd6c019cf9c8237a774e0e63d444e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a60a46898ebd5b85c1ea6210e62e25d0899442c4873dee4ec13182eec3b7ae9c9a89752a8b7d1f2e62b35d2e183a7f09d61902134291d3f2113593b03fb4f9c
|
7
|
+
data.tar.gz: 917579ddbe4b7549e0de1ea83c7e37f1c6ecc50fb0ad90b6d7db8a3b44efef6247c81661e9606f4220561ad8aa2fcbb8b35334ecc7dd4c3c2e5262f024ace79d
|
data/README.md
CHANGED
@@ -1,28 +1,91 @@
|
|
1
1
|
# YAMG
|
2
2
|
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
4
|
+
_____ _____ _____ ______ _______ _____
|
5
|
+
|\ \ / /| ___|\ \ | \/ \ ___|\ \
|
6
|
+
| \ \ / / | / /\ \ / /\ \ / /\ \
|
7
|
+
| \____\/ / /| | | | / /\ / /\ || | |____|
|
8
|
+
\ | / / / | |__| | / /\ \_/ / / /|| | ____
|
9
|
+
\|___/ / / | .--. || | \|_|/ / / || | | |
|
10
|
+
/ / / | | | || | | | || | |_, |
|
11
|
+
/____/ / |____| |____||\____\ |____| /|\ ___\___/ /|
|
12
|
+
|` | / | | | || | | | | / | | /____ / |
|
13
|
+
|_____|/ |____| |____| \|____| |____|/ \|___| | /
|
14
|
+
\|____|/
|
15
15
|
|
16
16
|
|
17
17
|
[![Gem Version](https://badge.fury.io/rb/yamg.png)](http://badge.fury.io/rb/yamg)
|
18
18
|
[![Dependency Status](https://gemnasium.com/nofxx/yamg.svg)](https://gemnasium.com/nofxx/yamg)
|
19
19
|
[![Build Status](https://travis-ci.org/nofxx/yamg.png?branch=master)](https://travis-ci.org/nofxx/yamg)
|
20
20
|
|
21
|
-
YAMG
|
21
|
+
YAMG - Yet Another Media Generator
|
22
|
+
|
22
23
|
|
23
24
|
## Install
|
24
25
|
|
25
|
-
|
26
|
+
Linux
|
27
|
+
|
28
|
+
nice-pkg-manager install imagemagick phantomjs ruby
|
29
|
+
gem install yamg
|
30
|
+
|
31
|
+
OSX
|
32
|
+
|
33
|
+
brew install imagemagick phantomjs ruby
|
34
|
+
gem install yamg
|
35
|
+
|
36
|
+
|
37
|
+
## Features
|
38
|
+
|
39
|
+
* Find best version (size) to use from icons folder.
|
40
|
+
* Splash screen/banner generation with gravity.
|
41
|
+
* Works with iOS/Android/Other mobile with Phonegap or Cordova.
|
26
42
|
|
27
43
|
|
28
44
|
## Use
|
45
|
+
|
46
|
+
yamg
|
47
|
+
|
48
|
+
A `.yamg.yml` will be created on the folder.
|
49
|
+
|
50
|
+
### Icons
|
51
|
+
|
52
|
+
Multiple sizes:
|
53
|
+
Just save your files with the size in pixels first, example:
|
54
|
+
In the 'icons/' folder: '16-icon.png', '32-icon.png', '512-icon.png'.
|
55
|
+
YAMG will choose the best size for the case, and don't touch
|
56
|
+
the icon if sizes are a match.
|
57
|
+
|
58
|
+
It's ok to (or if you) have only one icon, make it >512px.
|
59
|
+
|
60
|
+
|
61
|
+
### Splash
|
62
|
+
|
63
|
+
The main splash image must be named 'center'.
|
64
|
+
Gravity!
|
65
|
+
Just save you files with the names: 'north', 'northeast', 'south'...
|
66
|
+
Gravity will put em in the correct place, with a lil padding.
|
67
|
+
|
68
|
+
|
69
|
+
### Media
|
70
|
+
|
71
|
+
Addional media.
|
72
|
+
There's also media generator for app stores.
|
73
|
+
|
74
|
+
|
75
|
+
## Screenshots (phantomjs)
|
76
|
+
|
77
|
+
Soon.
|
78
|
+
|
79
|
+
### Support
|
80
|
+
|
81
|
+
* Web
|
82
|
+
* Rails
|
83
|
+
* iOS Project
|
84
|
+
* Android Project
|
85
|
+
* Cordova (platforms/*)
|
86
|
+
* Phonegap (www/res)
|
87
|
+
* App Store
|
88
|
+
* Play Store
|
89
|
+
* Facebook
|
90
|
+
* Twitter
|
91
|
+
* Write your own (really easy, fork and change yml)
|
data/bin/yamg
CHANGED
data/lib/yamg/cli.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
module YAMG
|
2
|
+
# Command line interface
|
3
|
+
class CLI
|
4
|
+
attr_accessor :works
|
5
|
+
|
6
|
+
def initialize(argv)
|
7
|
+
puts
|
8
|
+
puts Rainbow(' Y A M G').red
|
9
|
+
puts
|
10
|
+
|
11
|
+
return YAMG.init if argv.join =~ /init/
|
12
|
+
YAMG.load_config # (argv)
|
13
|
+
@works = YAMG.config['compile']
|
14
|
+
compile
|
15
|
+
screenshot
|
16
|
+
end
|
17
|
+
|
18
|
+
def setup_for(opts)
|
19
|
+
case opts
|
20
|
+
when Hash then opts
|
21
|
+
when String then { 'path' => opts }
|
22
|
+
when TrueClass then { 'path' => './media' }
|
23
|
+
else fail
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def compile_icon(i, size, setup)
|
28
|
+
folder = setup['icon'] || YAMG.config['icon']['path']
|
29
|
+
round = setup['rounded'] || YAMG.config['icon']['rounded']
|
30
|
+
icon = Icon.new(folder, size, setup).image
|
31
|
+
to = File.join(setup['path'], i)
|
32
|
+
YAMG.write_out(icon, to)
|
33
|
+
# puts Rainbow("Icon #{size}px #{i} #{setup['path']}").black
|
34
|
+
print Rainbow('I').black
|
35
|
+
end
|
36
|
+
|
37
|
+
def compile_splash(s, size, setup)
|
38
|
+
path = setup['splash'] || YAMG.config['splash']['path']
|
39
|
+
splash = Splash.new(path, size, YAMG.config['splash']['background']).image
|
40
|
+
to = File.join(setup['path'], s)
|
41
|
+
YAMG.write_out(splash, to)
|
42
|
+
# puts Rainbow("Splash #{size.join('x')}px #{s} -> #{setup['path']}").black
|
43
|
+
print Rainbow('S').black
|
44
|
+
end
|
45
|
+
|
46
|
+
def compile_work(scope, opts)
|
47
|
+
setup = setup_for(opts)
|
48
|
+
|
49
|
+
if (task = YAMG::TEMPLATES[scope])
|
50
|
+
#Thread.new do # 200% speed up with 8 cores
|
51
|
+
task['icons'].each { |i, d| Thread.new { compile_icon(i, d, setup) }}
|
52
|
+
return unless task['splash']
|
53
|
+
task['splash'].each { |s, d| Thread.new { compile_splash(s, d, setup) }}
|
54
|
+
#end
|
55
|
+
else
|
56
|
+
# puts 'Custom job!'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def compile(scope = nil)
|
61
|
+
time = Time.now
|
62
|
+
works.select! { |w| w =~ scope } if scope
|
63
|
+
works.each { |out, opts| compile_work(out, opts) }
|
64
|
+
works.select! { |w| w =~ scope } if scope
|
65
|
+
puts Rainbow("Working on #{works.keys.join(', ')}").yellow
|
66
|
+
|
67
|
+
YAMG.config['screenshots'].each do |ss|
|
68
|
+
Thread.new { Screenshot.new(ss).work('./media') }
|
69
|
+
end
|
70
|
+
puts Rainbow(Thread.list.size.to_s + ' jobs').black
|
71
|
+
Thread.list.reject { |t| t == Thread.current }.each(&:join)
|
72
|
+
puts Rainbow('-' * 59).black
|
73
|
+
puts Rainbow("Done compile #{Time.now - time}").red
|
74
|
+
end
|
75
|
+
|
76
|
+
def screenshot
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/yamg/icon.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
module YAMG
|
2
|
+
#
|
3
|
+
# ICONS
|
4
|
+
#
|
5
|
+
#
|
6
|
+
class Icon
|
7
|
+
attr_accessor :src, :size, :rounded, :icons
|
8
|
+
|
9
|
+
def initialize(src, size, rounded = false)
|
10
|
+
fail if src.nil? || src.empty?
|
11
|
+
@src = src
|
12
|
+
@size = size
|
13
|
+
@rounded = rounded
|
14
|
+
@icons = YAMG.load_images(src)
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_closest_gte_icon
|
18
|
+
return icons.max_by(&:to_i) if icons.map(&:to_i).max < size
|
19
|
+
icons.min_by do |f|
|
20
|
+
# n = x.match(/\d+/).to_s.to_i
|
21
|
+
n = f.to_i
|
22
|
+
size > n ? Float::INFINITY : n
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def image
|
27
|
+
path = File.join(src, find_closest_gte_icon)
|
28
|
+
img = MiniMagick::Image.open(path)
|
29
|
+
img.resize size # "NxN"
|
30
|
+
rounded ? round(img) : img
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Maybe this can be smaller, terminal equivalent:
|
35
|
+
# convert
|
36
|
+
# -size 512x512 xc:none
|
37
|
+
# -draw "roundrectangle 0,0,512,512,55,55" mask.png
|
38
|
+
# convert icon.png
|
39
|
+
# -matte mask.png
|
40
|
+
# -compose DstIn
|
41
|
+
# -composite picture_with_rounded_corners.png
|
42
|
+
# https://gist.github.com/artemave/c20e7450af866f5e7735
|
43
|
+
def round(img, r = 14)
|
44
|
+
size = img.dimensions.join(',')
|
45
|
+
r = img.dimensions.max / r
|
46
|
+
radius = [r, r].join(',')
|
47
|
+
|
48
|
+
mask = MiniMagick::Image.open(img.path)
|
49
|
+
mask.format 'png'
|
50
|
+
|
51
|
+
mask.combine_options do |m|
|
52
|
+
m.alpha 'transparent'
|
53
|
+
m.background 'none'
|
54
|
+
m.draw "roundrectangle 0,0,#{size},#{radius}"
|
55
|
+
end
|
56
|
+
|
57
|
+
overlay = ::MiniMagick::Image.open img.path
|
58
|
+
overlay.format 'png'
|
59
|
+
|
60
|
+
overlay.combine_options do |o|
|
61
|
+
o.alpha 'transparent'
|
62
|
+
o.background 'none'
|
63
|
+
o.draw "roundrectangle 0,0,#{size},#{radius}"
|
64
|
+
end
|
65
|
+
|
66
|
+
masked = img.composite(mask, 'png') do |i|
|
67
|
+
i.alpha 'set'
|
68
|
+
i.compose 'DstIn'
|
69
|
+
end
|
70
|
+
|
71
|
+
masked.composite(overlay, 'png') do |i|
|
72
|
+
i.compose 'Over'
|
73
|
+
end
|
74
|
+
masked
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'screencap'
|
2
|
+
# require 'smartshot'
|
3
|
+
|
4
|
+
module YAMG
|
5
|
+
#
|
6
|
+
# Screenshot from multiple providers
|
7
|
+
#
|
8
|
+
class Screenshot
|
9
|
+
# include Capybara::DSL
|
10
|
+
attr_accessor :url, :size, :command
|
11
|
+
|
12
|
+
# Uses PhantomJS
|
13
|
+
def initialize(ss)
|
14
|
+
require 'smartshot'
|
15
|
+
require 'capybara'
|
16
|
+
require 'capybara/poltergeist'
|
17
|
+
@name, opts = *ss
|
18
|
+
uri = URI.parse(opts['url'])
|
19
|
+
@url = "http://#{uri}"
|
20
|
+
@size = opts['size'].split(/\s?,\s?/)
|
21
|
+
# @fetcher = Smartshot::Screenshot.new(window_size: @size)
|
22
|
+
@fetcher = Screencap::Fetcher.new(@url)
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
def work(path)
|
27
|
+
# visit(url)
|
28
|
+
# page.save_screenshot("#{path}/#{@name}.png")
|
29
|
+
# @fetcher.take_screenshot!(url: url, output: "#{path}/#{@name}.png")
|
30
|
+
@fetcher.fetch(output: "#{path}/#{@name}.png", width: @size[0], height: @size[1])
|
31
|
+
puts Rainbow("SS #{url} #{size}").black
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/lib/yamg/splash.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module YAMG
|
2
|
+
#
|
3
|
+
# SPLASH
|
4
|
+
#
|
5
|
+
#
|
6
|
+
class Splash
|
7
|
+
attr_accessor :src, :bg, :size, :icons, :img
|
8
|
+
|
9
|
+
def initialize(src, size, background)
|
10
|
+
@src = src
|
11
|
+
@size = size
|
12
|
+
@bg = background
|
13
|
+
@icons = YAMG.load_images(src)
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Center image
|
18
|
+
#
|
19
|
+
def splash_center(center)
|
20
|
+
icon_size = size.max / 4
|
21
|
+
img.resize icon_size if img.dimensions.max >= icon_size
|
22
|
+
img.background bg if bg
|
23
|
+
img.combine_options do |o|
|
24
|
+
o.gravity 'center'
|
25
|
+
o.extent size.join('x') # "WxH"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def compose(other, name)
|
30
|
+
img.composite(other) do |o|
|
31
|
+
o.compose 'Over'
|
32
|
+
o.gravity File.basename(name, '.*')
|
33
|
+
o.geometry '+40%+40%'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# Composite 9 gravity
|
39
|
+
#
|
40
|
+
def splash_composite(base)
|
41
|
+
max = base.dimensions.min / 9
|
42
|
+
icons.reduce(base) do |img, over|
|
43
|
+
other = MiniMagick::Image.open(File.join(src, over))
|
44
|
+
other.resize(max) if other.dimensions.max >= max
|
45
|
+
compose(other, over)
|
46
|
+
end
|
47
|
+
base
|
48
|
+
end
|
49
|
+
|
50
|
+
def image
|
51
|
+
center = icons.find { |i| i =~ /center/ }
|
52
|
+
icons.delete(center)
|
53
|
+
self.img = MiniMagick::Image.open(File.join(src, center))
|
54
|
+
|
55
|
+
splash_composite(splash_center(center))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
android:
|
2
|
+
icons:
|
3
|
+
'res/drawable/icon.png': 96
|
4
|
+
'res/drawable-ldpi/icon.png': 36
|
5
|
+
'res/drawable-mdpi/icon.png': 48
|
6
|
+
'res/drawable-hdpi/icon.png': 72
|
7
|
+
'res/drawable-xhdpi/icon.png': 96
|
8
|
+
'res/drawable-xxhdpi/icon.png': 256
|
9
|
+
'bin/res/drawable/icon.png': 96
|
10
|
+
'bin/res/drawable-ldpi/icon.png': 36
|
11
|
+
'bin/res/drawable-mdpi/icon.png': 48
|
12
|
+
'bin/res/drawable-hdpi/icon.png': 72
|
13
|
+
'bin/res/drawable-xhdpi/icon.png': 96
|
14
|
+
'ant-build/res/drawable/icon.png': 96
|
15
|
+
'ant-build/res/drawable-ldpi/icon.png': 36
|
16
|
+
'ant-build/res/drawable-mdpi/icon.png': 48
|
17
|
+
'ant-build/res/drawable-hdpi/icon.png': 72
|
18
|
+
'ant-build/res/drawable-xhdpi/icon.png': 96
|
19
|
+
splash:
|
20
|
+
'res/drawable-port-ldpi/screen.png': [200, 320]
|
21
|
+
'res/drawable-port-mdpi/screen.png': [320, 480]
|
22
|
+
'res/drawable-port-hdpi/screen.png': [480, 800]
|
23
|
+
'res/drawable-port-xhdpi/screen.png': [720, 1280]
|
24
|
+
'res/drawable-land-ldpi/screen.png': [320, 200]
|
25
|
+
'res/drawable-land-mdpi/screen.png': [480, 320]
|
26
|
+
'res/drawable-land-hdpi/screen.png': [800, 480]
|
27
|
+
'res/drawable-land-xhdpi/screen.png': [1280, 720]
|
28
|
+
'bin/res/drawable-port-ldpi/screen.png': [200, 320]
|
29
|
+
'bin/res/drawable-port-mdpi/screen.png': [320, 480]
|
30
|
+
'bin/res/drawable-port-hdpi/screen.png': [480, 800]
|
31
|
+
'bin/res/drawable-port-xhdpi/screen.png': [720, 1280]
|
32
|
+
'bin/res/drawable-land-ldpi/screen.png': [320, 200]
|
33
|
+
'bin/res/drawable-land-mdpi/screen.png': [480, 320]
|
34
|
+
'bin/res/drawable-land-hdpi/screen.png': [800, 480]
|
35
|
+
'bin/res/drawable-land-xhdpi/screen.png': [1280, 720]
|
36
|
+
'ant-build/res/drawable-port-ldpi/screen.png': [200, 320]
|
37
|
+
'ant-build/res/drawable-port-mdpi/screen.png': [320, 480]
|
38
|
+
'ant-build/res/drawable-port-hdpi/screen.png': [480, 800]
|
39
|
+
'ant-build/res/drawable-port-xhdpi/screen.png': [720, 1280]
|
40
|
+
'ant-build/res/drawable-land-ldpi/screen.png': [320, 200]
|
41
|
+
'ant-build/res/drawable-land-mdpi/screen.png': [480, 320]
|
42
|
+
'ant-build/res/drawable-land-hdpi/screen.png': [800, 480]
|
43
|
+
'ant-build/res/drawable-land-xhdpi/screen.png': [1280, 720]
|
44
|
+
|
45
|
+
|
46
|
+
ios:
|
47
|
+
icons:
|
48
|
+
'Resources/icons/icon.png': 57
|
49
|
+
'Resources/icons/icon@2x.png': 114
|
50
|
+
'Resources/icons/icon-40.png': 40
|
51
|
+
'Resources/icons/icon-40@2x.png': 80
|
52
|
+
'Resources/icons/icon-40@3x.png': 120
|
53
|
+
'Resources/icons/icon-50.png': 50
|
54
|
+
'Resources/icons/icon-50@2x.png': 100
|
55
|
+
'Resources/icons/icon-60.png': 60
|
56
|
+
'Resources/icons/icon-60@2x.png': 120
|
57
|
+
'Resources/icons/icon-60@3x.png': 180
|
58
|
+
'Resources/icons/icon-72.png': 72
|
59
|
+
'Resources/icons/icon-72@2x.png': 144
|
60
|
+
'Resources/icons/icon-76.png': 76
|
61
|
+
'Resources/icons/icon-76@2x.png': 152
|
62
|
+
'Resources/icons/icon-120.png': 120
|
63
|
+
'Resources/icons/icon-small.png': 29
|
64
|
+
'Resources/icons/icon-small@2x.png': 58
|
65
|
+
'Resources/icons/icon-small@3x.png': 87
|
66
|
+
splash:
|
67
|
+
'Resources/splash/Default~iphone.png': [320, 480]
|
68
|
+
'Resources/splash/Default@2x~iphone.png': [640, 960]
|
69
|
+
'Resources/splash/Default-Landscape@2x~ipad.png': [2048, 1536]
|
70
|
+
'Resources/splash/Default-Landscape~ipad.png': [1024, 768]
|
71
|
+
'Resources/splash/Default-Portrait@2x~ipad.png': [1536, 2048]
|
72
|
+
'Resources/splash/Default-Portrait~ipad.png': [768, 1024]
|
73
|
+
'Resources/splash/Default-568h@2x~iphone.png': [640, 1136]
|
74
|
+
'Resources/splash/Default-667h.png': [750, 1344]
|
75
|
+
'Resources/splash/Default-736h.png': [1242, 2208]
|
76
|
+
'Resources/splash/Default-Landscape-736h.png' : [2208, 1242]
|
77
|
+
|
78
|
+
|
79
|
+
phonegap:
|
80
|
+
icon:
|
81
|
+
'icon/android/icon-36-ldpi.png': 36
|
82
|
+
'icon/android/icon-48-mdpi.png': 48
|
83
|
+
'icon/android/icon-72-hdpi.png': 72
|
84
|
+
'icon/android/icon-96-xhdpi.png': 96
|
85
|
+
'icon/blackberry/icon-80.png': 80
|
86
|
+
'icon/ios/icon-57.png': 57
|
87
|
+
'icon/ios/icon-57-2x.png': 114
|
88
|
+
'icon/ios/icon-72.png': 72
|
89
|
+
'icon/webos/icon-64.png': 64
|
90
|
+
'icon/windows-phone/icon-173-tile.png': 173
|
91
|
+
'icon/windows-phone/icon-62-tile.png': 62
|
92
|
+
'icon/windows-phone/icon-48.png': 48
|
93
|
+
splash:
|
94
|
+
'screen/android/screen-ldpi-landscape.png': [200, 320]
|
95
|
+
'screen/android/screen-mdpi-landscape.png': [320, 480]
|
96
|
+
'screen/android/screen-hdpi-landscape.png': [480, 800]
|
97
|
+
'screen/android/screen-xhdpi-landscape.png': [720, 1280]
|
98
|
+
'screen/android/screen-ldpi-portrait.png': [320, 200]
|
99
|
+
'screen/android/screen-mdpi-portrait.png': [480, 320]
|
100
|
+
'screen/android/screen-hdpi-portrait.png': [800, 480]
|
101
|
+
'screen/android/screen-xhdpi-portrait.png': [1280, 720]
|
102
|
+
'screen/blackberry/screen-225': [225]
|
103
|
+
'screen/ios/screen-ipad-landscape-2x.png': [2048, 1536]
|
104
|
+
'screen/ios/screen-ipad-landscape.png': [1024, 768]
|
105
|
+
'screen/ios/screen-ipad-portrait-2x.png': [1536, 2048]
|
106
|
+
'screen/ios/screen-ipad-portrait.png': [768, 1024]
|
107
|
+
'screen/ios/screen-iphone-landscape.png': [480, 320]
|
108
|
+
'screen/ios/screen-iphone-landscape-2x.png': [960, 640]
|
109
|
+
'screen/ios/screen-iphone-portrait-2x.png': [640, 960]
|
110
|
+
'screen/ios/screen-iphone-portrait-568h-2x.png': [640, 1136]
|
111
|
+
'screen/ios/screen-iphone-portrait.png': [320, 480]
|
112
|
+
'screen/ios/screen-iDefault~iphone.png': [320, 480]
|
113
|
+
'screen/ios/screen-iDefault-667h.png': [750, 1344]
|
114
|
+
'screen/ios/screen-iDefault-736h.png': [1242, 2208]
|
115
|
+
'screen/ios/screen-iDefault-Landscape-736h.png': [2208, 1242]
|
116
|
+
'screen/windows-phone/screen-portrait.jpg': [720, 1280]
|
117
|
+
|
118
|
+
|
119
|
+
web:
|
120
|
+
icons:
|
121
|
+
'icon.png': 256
|
122
|
+
media:
|
123
|
+
'media.png': 256
|
124
|
+
|
125
|
+
|
126
|
+
rails:
|
127
|
+
icons:
|
128
|
+
'public/favicon.png': 16
|
129
|
+
'public/favicon.ico': 16
|
130
|
+
'public/icon.png': 512
|
131
|
+
'app/assets/images/icon.png': 512
|
132
|
+
'app/assets/images/favicon.png': 16
|
133
|
+
media:
|
134
|
+
'public/logo.png': 512
|
135
|
+
|
136
|
+
|
137
|
+
twitter:
|
138
|
+
icons:
|
139
|
+
'icon.png': 256
|
140
|
+
|
141
|
+
|
142
|
+
google:
|
143
|
+
icons:
|
144
|
+
'icon.png': 512
|
145
|
+
'icon1024.png': 1024
|
146
|
+
'180.png': 180
|
147
|
+
splash:
|
148
|
+
'splash.png': [1024, 768]
|
149
|
+
|
150
|
+
apple:
|
151
|
+
icons:
|
152
|
+
'icon.png': 1024
|
153
|
+
'icon16.png': 16
|
154
|
+
splash:
|
155
|
+
'splash.png': [1024, 768]
|
156
|
+
screenshots:
|
157
|
+
|
158
|
+
{filename: "android-10in-1280x720-land", width: 1280, height: 720, savePath: 'Media/android/screenshots/10in'},
|
159
|
+
{filename: "android-10in-2048x1152-land", width: 2048, height: 1152, savePath: 'Media/android/screenshots/10in'},
|
160
|
+
{filename: "android-7in-1280x800-land", width: 1280, height: 800, savePath: 'Media/android/screenshots/7in'},
|
161
|
+
{filename: "android-10in-1280x720-port", width: 720, height: 1280, savePath: 'Media/android/screenshots/10in'},
|
162
|
+
{filename: "android-10in-2048x1152-port", width: 1152, height: 2048, savePath: 'Media/android/screenshots/10in'},
|
163
|
+
{filename: "android-7in-1280x800-port", width: 800, height: 1280, savePath: 'Media/android/screenshots/7in'},
|
164
|
+
{filename: "android-4in-1280x720-land", width: 1920, height: 1080, savePath: 'Media/android/screenshots/4in'},
|
165
|
+
{filename: "android-4in-1280x720-port", width: 1080, height: 1920, savePath: 'Media/android/screenshots/4in'},
|
166
|
+
{filename: "ipad-1024x768-land", width: 1024, height: 768, savePath: 'Media/ios/screenshots/ipad'},
|
167
|
+
{
|
168
|
+
filename: "ipadretina-2048x1536-land",
|
169
|
+
width: 2048,
|
170
|
+
height: 1536,
|
171
|
+
devicePixelRatio: 2,
|
172
|
+
savePath: 'Media/ios/screenshots/ipadRetina'
|
173
|
+
},
|
174
|
+
{filename: "iphone4-960x640-land", width: 960, height: 640, savePath: 'Media/ios/screenshots/iphone4'},
|
175
|
+
{filename: "iphone5-1136x640-land", width: 1136, height: 640, savePath: 'Media/ios/screenshots/iphone5'},
|
176
|
+
{filename: "ipad-1024x768-port", width: 768, height: 1024, savePath: 'Media/ios/screenshots/ipad'},
|
177
|
+
{
|
178
|
+
filename: "ipadretina-2048x1536-port",
|
179
|
+
width: 1536,
|
180
|
+
height: 2048,
|
181
|
+
devicePixelRatio: 2,
|
182
|
+
savePath: 'Media/ios/screenshots/ipadRetina'
|
183
|
+
},
|
184
|
+
{filename: "iphone4-640x960-port", width: 640, height: 960, savePath: 'Media/ios/screenshots/iphone4'},
|
185
|
+
{filename: "iphone5-640x1136-port", width: 640, height: 1136, savePath: 'Media/ios/screenshots/iphone5'},
|
186
|
+
{filename: "iphone6p-1080x1920-port", width: 1080, height: 1920, savePath: 'Media/ios/screenshots/iphone6p'},
|
187
|
+
{filename: "iphone6p-1920x1080-land", width: 1920, height: 1080, savePath: 'Media/ios/screenshots/iphone6p'},
|
188
|
+
{filename: "iphone6-1334x750-land", width: 1334, height: 750, savePath: 'Media/ios/screenshots/iphone6'},
|
189
|
+
{filename: "iphone6-750x1334-port", width: 750, height: 1334, savePath: 'Media/ios/screenshots/iphone6'}
|
190
|
+
]
|
191
|
+
|
192
|
+
facebook:
|
193
|
+
icons:
|
194
|
+
'icon.png': 1024
|
195
|
+
'icon16.png': 16
|
196
|
+
splash:
|
197
|
+
'splash.png': [1024, 768]
|
data/lib/yamg/version.rb
CHANGED
data/lib/yamg/yamg.yml
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
#
|
2
|
+
# YAMG Configuration
|
3
|
+
#
|
4
|
+
|
5
|
+
# Main icon
|
6
|
+
icon:
|
7
|
+
path: 'icons' # path to icons folder
|
8
|
+
rounded: true # defaults to false
|
9
|
+
background: false # or color RGB
|
10
|
+
|
11
|
+
# Splash screen
|
12
|
+
splash:
|
13
|
+
path: 'splash'
|
14
|
+
background: '#fff6d5' # or color RGB
|
15
|
+
|
16
|
+
# Icon + name for instance
|
17
|
+
media:
|
18
|
+
path: 'media.png'
|
19
|
+
background: false
|
20
|
+
|
21
|
+
#
|
22
|
+
# What to do?
|
23
|
+
#
|
24
|
+
compile:
|
25
|
+
|
26
|
+
# Web projects
|
27
|
+
#
|
28
|
+
web: true
|
29
|
+
# Ruby on rails
|
30
|
+
rails:
|
31
|
+
path: '/path/to/rails/proj'
|
32
|
+
icon: './alpha' # Using another icon src folder
|
33
|
+
|
34
|
+
# Mobile
|
35
|
+
#
|
36
|
+
# phonegap: '../path/to/project/www/res'
|
37
|
+
# cordova: 'soon shortcut'
|
38
|
+
# Cordova/iOS project
|
39
|
+
ios: '/path/to/project/platforms/ios/ProjectName/'
|
40
|
+
# Cordova/Android project
|
41
|
+
android: '/path/to/project/platforms/android/'
|
42
|
+
# winos: '../proj'
|
43
|
+
|
44
|
+
# Assets for web stores/players
|
45
|
+
#
|
46
|
+
# Compiles to media/playstore
|
47
|
+
apple: true
|
48
|
+
# Compiles to media/playstore
|
49
|
+
google: true
|
50
|
+
# Compiles to media/playstore
|
51
|
+
twitter: true
|
52
|
+
# Compiles to media/playstore
|
53
|
+
facebook: true
|
54
|
+
# Compiles to media/custom
|
55
|
+
custom:
|
56
|
+
icons: [32, 64, 128]
|
57
|
+
medias: [400, 800]
|
58
|
+
|
59
|
+
screenshots:
|
60
|
+
home:
|
61
|
+
url: 'notabe.com'
|
data/lib/yamg.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'rainbow'
|
3
|
+
require 'screencap'
|
3
4
|
require 'mini_magick'
|
4
5
|
|
5
6
|
MiniMagick.processor = :gm if ENV['gm']
|
@@ -7,394 +8,59 @@ MiniMagick.processor = :gm if ENV['gm']
|
|
7
8
|
#
|
8
9
|
# Yet Another Media Generator
|
9
10
|
#
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
'
|
31
|
-
|
32
|
-
'ant-build/res/drawable/icon.png' => 96,
|
33
|
-
'ant-build/res/drawable-ldpi/icon.png' => 36,
|
34
|
-
'ant-build/res/drawable-mdpi/icon.png' => 48,
|
35
|
-
'ant-build/res/drawable-hdpi/icon.png' => 72,
|
36
|
-
'ant-build/res/drawable-xhdpi/icon.png' => 96
|
37
|
-
},
|
38
|
-
splash: {
|
39
|
-
'res/drawable-port-ldpi/screen.png' => [200, 320],
|
40
|
-
'res/drawable-port-mdpi/screen.png' => [320, 480],
|
41
|
-
'res/drawable-port-hdpi/screen.png' => [480, 800],
|
42
|
-
'res/drawable-port-xhdpi/screen.png' => [720, 1280],
|
43
|
-
'res/drawable-land-ldpi/screen.png' => [320, 200],
|
44
|
-
'res/drawable-land-mdpi/screen.png' => [480, 320],
|
45
|
-
'res/drawable-land-hdpi/screen.png' => [800, 480],
|
46
|
-
'res/drawable-land-xhdpi/screen.png' => [1280, 720],
|
47
|
-
'bin/res/drawable-port-ldpi/screen.png' => [200, 320],
|
48
|
-
'bin/res/drawable-port-mdpi/screen.png' => [320, 480],
|
49
|
-
'bin/res/drawable-port-hdpi/screen.png' => [480, 800],
|
50
|
-
'bin/res/drawable-port-xhdpi/screen.png' => [720, 1280],
|
51
|
-
'bin/res/drawable-land-ldpi/screen.png' => [320, 200],
|
52
|
-
'bin/res/drawable-land-mdpi/screen.png' => [480, 320],
|
53
|
-
'bin/res/drawable-land-hdpi/screen.png' => [800, 480],
|
54
|
-
'bin/res/drawable-land-xhdpi/screen.png' => [1280, 720],
|
55
|
-
'ant-build/res/drawable-port-ldpi/screen.png' => [200, 320],
|
56
|
-
'ant-build/res/drawable-port-mdpi/screen.png' => [320, 480],
|
57
|
-
'ant-build/res/drawable-port-hdpi/screen.png' => [480, 800],
|
58
|
-
'ant-build/res/drawable-port-xhdpi/screen.png' => [720, 1280],
|
59
|
-
'ant-build/res/drawable-land-ldpi/screen.png' => [320, 200],
|
60
|
-
'ant-build/res/drawable-land-mdpi/screen.png' => [480, 320],
|
61
|
-
'ant-build/res/drawable-land-hdpi/screen.png' => [800, 480],
|
62
|
-
'ant-build/res/drawable-land-xhdpi/screen.png' => [1280, 720]
|
63
|
-
}
|
64
|
-
},
|
65
|
-
|
66
|
-
#
|
67
|
-
# iOS cordova/phonegap
|
68
|
-
#
|
69
|
-
ios: {
|
70
|
-
icons: {
|
71
|
-
'Resources/icons/icon.png' => 57,
|
72
|
-
'Resources/icons/icon@2x.png' => 114,
|
73
|
-
'Resources/icons/icon-40.png' => 40,
|
74
|
-
'Resources/icons/icon-40@2x.png' => 80,
|
75
|
-
'Resources/icons/icon-40@3x.png' => 120,
|
76
|
-
'Resources/icons/icon-50.png' => 50,
|
77
|
-
'Resources/icons/icon-50@2x.png' => 100,
|
78
|
-
'Resources/icons/icon-60.png' => 60,
|
79
|
-
'Resources/icons/icon-60@2x.png' => 120,
|
80
|
-
'Resources/icons/icon-60@3x.png' => 180,
|
81
|
-
'Resources/icons/icon-72.png' => 72,
|
82
|
-
'Resources/icons/icon-72@2x.png' => 144,
|
83
|
-
'Resources/icons/icon-76.png' => 76,
|
84
|
-
'Resources/icons/icon-76@2x.png' => 152,
|
85
|
-
'Resources/icons/icon-120.png' => 120,
|
86
|
-
'Resources/icons/icon-small.png' => 29,
|
87
|
-
'Resources/icons/icon-small@2x.png' => 58,
|
88
|
-
'Resources/icons/icon-small@3x.png' => 87
|
89
|
-
},
|
90
|
-
splash: {
|
91
|
-
'Resources/splash/Default~iphone.png' => [320, 480],
|
92
|
-
'Resources/splash/Default@2x~iphone.png' => [640, 960],
|
93
|
-
'Resources/splash/Default-Landscape@2x~ipad.png' => [2048, 1536],
|
94
|
-
'Resources/splash/Default-Landscape~ipad.png' => [1024, 768],
|
95
|
-
'Resources/splash/Default-Portrait@2x~ipad.png' => [1536, 2048],
|
96
|
-
'Resources/splash/Default-Portrait~ipad.png' => [768, 1024],
|
97
|
-
'Resources/splash/Default-568h@2x~iphone.png' => [640, 1136],
|
98
|
-
'Resources/splash/Default-667h.png' => [750, 1344],
|
99
|
-
'Resources/splash/Default-736h.png' => [1242, 2208],
|
100
|
-
'Resources/splash/Default-Landscape-736h.png' => [2208, 1242]
|
101
|
-
}
|
102
|
-
},
|
103
|
-
|
104
|
-
#
|
105
|
-
# Phonegap www/res/
|
106
|
-
#
|
107
|
-
phonegap: {
|
108
|
-
icon: {
|
109
|
-
'icon/android/icon-36-ldpi.png' => 36,
|
110
|
-
'icon/android/icon-48-mdpi.png' => 48,
|
111
|
-
'icon/android/icon-72-hdpi.png' => 72,
|
112
|
-
'icon/android/icon-96-xhdpi.png' => 96,
|
113
|
-
'icon/blackberry/icon-80.png' => 80,
|
114
|
-
'icon/ios/icon-57.png' => 57,
|
115
|
-
'icon/ios/icon-57-2x.png' => 114,
|
116
|
-
'icon/ios/icon-72.png' => 72,
|
117
|
-
'icon/webos/icon-64.png' => 64,
|
118
|
-
'icon/windows-phone/icon-173-tile.png' => 173,
|
119
|
-
'icon/windows-phone/icon-62-tile.png' => 62,
|
120
|
-
'icon/windows-phone/icon-48.png' => 48
|
121
|
-
},
|
122
|
-
splash: {
|
123
|
-
'screen/android/screen-ldpi-landscape.png' => [200, 320],
|
124
|
-
'screen/android/screen-mdpi-landscape.png' => [320, 480],
|
125
|
-
'screen/android/screen-hdpi-landscape.png' => [480, 800],
|
126
|
-
'screen/android/screen-xhdpi-landscape.png' => [720, 1280],
|
127
|
-
'screen/android/screen-ldpi-portrait.png' => [320, 200],
|
128
|
-
'screen/android/screen-mdpi-portrait.png' => [480, 320],
|
129
|
-
'screen/android/screen-hdpi-portrait.png' => [800, 480],
|
130
|
-
'screen/android/screen-xhdpi-portrait.png' => [1280, 720],
|
131
|
-
'screen/blackberry/screen-225' => [225],
|
132
|
-
'screen/ios/screen-ipad-landscape-2x.png' => [2048, 1536],
|
133
|
-
'screen/ios/screen-ipad-landscape.png' => [1024, 768],
|
134
|
-
'screen/ios/screen-ipad-portrait-2x.png' => [1536, 2048],
|
135
|
-
'screen/ios/screen-ipad-portrait.png' => [768, 1024],
|
136
|
-
'screen/ios/screen-iphone-landscape.png' => [480, 320],
|
137
|
-
'screen/ios/screen-iphone-landscape-2x.png' => [960, 640],
|
138
|
-
'screen/ios/screen-iphone-portrait-2x.png' => [640, 960],
|
139
|
-
'screen/ios/screen-iphone-portrait-568h-2x.png' => [640, 1136],
|
140
|
-
'screen/ios/screen-iphone-portrait.png' => [320, 480],
|
141
|
-
'screen/ios/screen-iDefault~iphone.png' => [320, 480],
|
142
|
-
'screen/ios/screen-iDefault-667h.png' => [750, 1344],
|
143
|
-
'screen/ios/screen-iDefault-736h.png' => [1242, 2208],
|
144
|
-
'screen/ios/screen-iDefault-Landscape-736h.png' => [2208, 1242],
|
145
|
-
'screen/windows-phone/screen-portrait.jpg' => [720, 1280]
|
146
|
-
}
|
147
|
-
},
|
148
|
-
|
149
|
-
#
|
150
|
-
# WWW
|
151
|
-
#
|
152
|
-
web: {
|
153
|
-
icons: {
|
154
|
-
'icon.png' => 256
|
155
|
-
},
|
156
|
-
media: {
|
157
|
-
'media.png' => 256
|
158
|
-
}
|
159
|
-
},
|
160
|
-
|
161
|
-
rails: {
|
162
|
-
icons: {
|
163
|
-
'public/favicon.png' => 16,
|
164
|
-
'public/favicon.ico' => 16,
|
165
|
-
'public/icon.png' => 512,
|
166
|
-
'app/assets/images/icon.png' => 512,
|
167
|
-
'app/assets/images/favicon.png' => 16
|
168
|
-
},
|
169
|
-
media: {
|
170
|
-
'public/logo.png' => 512
|
171
|
-
}
|
172
|
-
},
|
173
|
-
|
174
|
-
twitter: {
|
175
|
-
icons: {
|
176
|
-
'icon.png' => 256
|
177
|
-
}
|
178
|
-
},
|
179
|
-
|
180
|
-
#
|
181
|
-
# Play Store
|
182
|
-
#
|
183
|
-
google: {
|
184
|
-
icons: {
|
185
|
-
'icon.png' => 512,
|
186
|
-
'icon1024.png' => 1024, # [1024, 500]
|
187
|
-
'180.png' => 180, # 180, 120
|
188
|
-
},
|
189
|
-
splash: {
|
190
|
-
'splash.png' => [1024, 768]
|
191
|
-
}
|
192
|
-
},
|
193
|
-
|
194
|
-
#
|
195
|
-
# App Store
|
196
|
-
#
|
197
|
-
apple: {
|
198
|
-
icons: {
|
199
|
-
'icon.png' => 1024,
|
200
|
-
'icon16.png' => 16
|
201
|
-
},
|
202
|
-
splash: {
|
203
|
-
'splash.png' => [1024, 768]
|
204
|
-
}
|
205
|
-
},
|
206
|
-
|
207
|
-
facebook: {
|
208
|
-
icons: {
|
209
|
-
'icon.png' => 1024,
|
210
|
-
'icon16.png' => 16
|
211
|
-
},
|
212
|
-
splash: {
|
213
|
-
'splash.png' => [1024, 768]
|
214
|
-
}
|
215
|
-
}
|
216
|
-
}
|
217
|
-
|
218
|
-
def initialize
|
219
|
-
load_config
|
220
|
-
end
|
221
|
-
|
222
|
-
def load_config
|
223
|
-
self.config = YAML.load_file('./.yamg.yml').freeze
|
224
|
-
rescue Errno::ENOENT
|
225
|
-
puts 'Create config!'
|
226
|
-
exit 1
|
227
|
-
end
|
228
|
-
|
229
|
-
def setup_for(opts)
|
230
|
-
case opts
|
231
|
-
when Hash then opts
|
232
|
-
when String then { 'path' => opts }
|
233
|
-
when TrueClass then { 'path' => './media' }
|
234
|
-
else fail
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
#
|
239
|
-
# Writes image to disk
|
240
|
-
#
|
241
|
-
def write_out(img, path)
|
242
|
-
img.format File.extname(path)
|
243
|
-
FileUtils.mkdir_p File.dirname(path)
|
244
|
-
img.write(path)
|
245
|
-
rescue Errno::ENOENT
|
246
|
-
puts
|
247
|
-
puts Rainbow("Path not found '#{path}'").red
|
248
|
-
exit 1
|
249
|
-
end
|
250
|
-
|
251
|
-
def compile_work(scope, opts)
|
252
|
-
puts Rainbow("Working on #{scope}'").blue
|
253
|
-
setup = setup_for(opts)
|
254
|
-
|
255
|
-
if (t = TEMPLATES[scope.to_sym])
|
256
|
-
Thread.new do # 200% speed up with 8 cores
|
257
|
-
icon_work(t[:icons], setup)
|
258
|
-
splash_work(t[:splash], setup) if t[:splash]
|
11
|
+
module YAMG
|
12
|
+
autoload :CLI, 'yamg/cli'
|
13
|
+
autoload :Icon, 'yamg/icon'
|
14
|
+
autoload :Splash, 'yamg/splash'
|
15
|
+
autoload :Screenshot, 'yamg/screenshot'
|
16
|
+
|
17
|
+
# Load template works
|
18
|
+
TEMPLATES = YAML.load_file(
|
19
|
+
File.join(File.dirname(__FILE__), 'yamg', 'templates.yaml')
|
20
|
+
)
|
21
|
+
|
22
|
+
# def initialize(conf = './.yamg.yml')
|
23
|
+
# load_config(conf)
|
24
|
+
# end
|
25
|
+
class << self
|
26
|
+
attr_accessor :config
|
27
|
+
|
28
|
+
def init
|
29
|
+
file = './.yamg.yml'
|
30
|
+
if File.exist?(file)
|
31
|
+
puts "File exists: '#{file}'"
|
32
|
+
exit 1
|
259
33
|
end
|
260
|
-
|
261
|
-
|
34
|
+
puts Rainbow('Creating your configuration').black
|
35
|
+
src = File.join(File.dirname(__FILE__), 'yamg', 'yamg.yml')
|
36
|
+
FileUtils.cp(src, file)
|
262
37
|
end
|
263
|
-
end
|
264
|
-
|
265
|
-
def compile(scope = nil)
|
266
|
-
time = Time.now
|
267
|
-
works = config['compile']
|
268
|
-
works.select! { |w| w =~ scope } if scope
|
269
|
-
works.each { |out, opts| compile_work(out, opts) }
|
270
|
-
Thread.list.reject { |t| t == Thread.current }.each(&:join)
|
271
|
-
puts Rainbow("Done compile #{Time.now - time}").red
|
272
|
-
end
|
273
|
-
|
274
|
-
#
|
275
|
-
#
|
276
|
-
# ICONS
|
277
|
-
#
|
278
|
-
#
|
279
|
-
def load_icons(path)
|
280
|
-
return [path] unless File.extname(path).empty?
|
281
|
-
Dir["#{path}/*.png"].map { |f| File.basename(f) }
|
282
|
-
end
|
283
|
-
|
284
|
-
def find_closest_gte_icon(size, icons)
|
285
|
-
return icons.max_by(&:to_i) if icons.map(&:to_i).max < size
|
286
|
-
icons.min_by do |f|
|
287
|
-
# n = x.match(/\d+/).to_s.to_i
|
288
|
-
n = f.to_i
|
289
|
-
size > n ? Float::INFINITY : n
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
def icon_work(files, setup)
|
294
|
-
path = setup['icon'] || config['icon']['path']
|
295
|
-
rounded = setup['rounded'] || config['icon']['rounded']
|
296
|
-
icons = load_icons(path)
|
297
|
-
puts Rainbow("Starting in #{path} with #{icons} | #{setup}").blue
|
298
|
-
files.each do |file, size|
|
299
|
-
from = File.join(path, find_closest_gte_icon(size, icons))
|
300
|
-
to = File.join(setup['path'], file)
|
301
|
-
puts "#{File.basename from} -> #{to} (#{size}px)"
|
302
|
-
image = MiniMagick::Image.open(from)
|
303
|
-
image.resize size # "NxN"
|
304
|
-
image = round(image) if rounded
|
305
|
-
write_out(image, to)
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
# https://gist.github.com/artemave/c20e7450af866f5e7735
|
310
|
-
def round(img, r = 14)
|
311
|
-
size = img.dimensions.join(',')
|
312
|
-
r = img.dimensions.max / r
|
313
|
-
radius = [r, r].join(',')
|
314
|
-
|
315
|
-
mask = MiniMagick::Image.open(img.path)
|
316
|
-
mask.format 'png'
|
317
|
-
|
318
|
-
mask.combine_options do |m|
|
319
|
-
m.alpha 'transparent'
|
320
|
-
m.background 'none'
|
321
|
-
m.draw "roundrectangle 0,0,#{size},#{radius}"
|
322
|
-
end
|
323
|
-
|
324
|
-
overlay = ::MiniMagick::Image.open img.path
|
325
|
-
overlay.format 'png'
|
326
38
|
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
39
|
+
def load_config(conf = './.yamg.yml')
|
40
|
+
self.config = YAML.load_file(conf).freeze
|
41
|
+
rescue Errno::ENOENT
|
42
|
+
puts Rainbow('Create config! Run: `yamg init`').red
|
43
|
+
exit 1
|
331
44
|
end
|
332
45
|
|
333
|
-
|
334
|
-
|
335
|
-
|
46
|
+
def load_images(dir)
|
47
|
+
return [dir] unless File.extname(dir).empty?
|
48
|
+
Dir["#{dir}/*.png"].map { |f| File.basename(f) }
|
336
49
|
end
|
337
50
|
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
# -composite picture_with_rounded_corners.png
|
350
|
-
end
|
351
|
-
|
352
|
-
#
|
353
|
-
#
|
354
|
-
# SPLASH
|
355
|
-
#
|
356
|
-
#
|
357
|
-
def splash_center(path, size, bg = config['splash']['background'])
|
358
|
-
icon_size = size.max / 4
|
359
|
-
image = MiniMagick::Image.open(path)
|
360
|
-
image.resize icon_size if image.dimensions.max >= icon_size
|
361
|
-
image.background bg if bg
|
362
|
-
image.combine_options do |o|
|
363
|
-
o.gravity 'center'
|
364
|
-
o.extent size.join('x') # "WxH"
|
365
|
-
end
|
366
|
-
end
|
367
|
-
|
368
|
-
def splash_composite(base, icons)
|
369
|
-
max = base.dimensions.min / 9
|
370
|
-
icons.reduce(base) do |img, over|
|
371
|
-
oimg = MiniMagick::Image.open(File.join(config['splash']['path'], over))
|
372
|
-
oimg.resize(max) if oimg.dimensions.max >= max
|
373
|
-
img.composite(oimg) do |o|
|
374
|
-
o.compose 'Over'
|
375
|
-
o.gravity File.basename(over, '.*')
|
376
|
-
o.geometry '+40%+40%'
|
377
|
-
end
|
378
|
-
end
|
379
|
-
end
|
380
|
-
|
381
|
-
def splash_work(screens, setup)
|
382
|
-
path = config['splash']['path']
|
383
|
-
icons = load_icons(path)
|
384
|
-
center = icons.find { |i| i =~ /center/ }
|
385
|
-
icons.delete(center)
|
386
|
-
|
387
|
-
puts Rainbow("Starting splashes | #{setup}").blue
|
388
|
-
screens.each do |file, size|
|
389
|
-
to = File.join(setup['path'], file)
|
390
|
-
image = splash_center(File.join(path, center), size)
|
391
|
-
write_out(splash_composite(image, icons), to)
|
51
|
+
#
|
52
|
+
# Writes image to disk
|
53
|
+
#
|
54
|
+
def write_out(img, path)
|
55
|
+
img.format File.extname(path)
|
56
|
+
FileUtils.mkdir_p File.dirname(path)
|
57
|
+
img.write(path)
|
58
|
+
rescue Errno::ENOENT
|
59
|
+
puts
|
60
|
+
puts Rainbow("Path not found '#{path}'").red
|
61
|
+
exit 1
|
392
62
|
end
|
393
63
|
end
|
394
|
-
|
395
|
-
def screenshot
|
396
|
-
puts 'SS'
|
397
|
-
end
|
398
64
|
end
|
399
65
|
|
400
66
|
# },
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
# require 'pry'
|
3
|
+
begin
|
4
|
+
require 'spec'
|
5
|
+
rescue LoadError
|
6
|
+
require 'rspec'
|
7
|
+
end
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
10
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
11
|
+
|
12
|
+
require 'yamg'
|
13
|
+
|
14
|
+
if ENV['CI']
|
15
|
+
require 'coveralls'
|
16
|
+
Coveralls.wear!
|
17
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe YAMG do
|
4
|
+
it 'should instantiate' do
|
5
|
+
stub_const('YAML', y = class_double('YAML'))
|
6
|
+
expect(y).to receive(:load_file).and_return({})
|
7
|
+
|
8
|
+
expect { YAMG.new }.to_not raise_error
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'stubbed' do
|
12
|
+
let :conf do
|
13
|
+
stub_const('YAML', class_double('YAML'))
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should read conf icon' do
|
17
|
+
expect(conf).to receive(:load_file).and_return(icon: {})
|
18
|
+
expect(YAMG.new.config).to eq(icon: {})
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'simple setup' do
|
22
|
+
it 'should map true to media' do
|
23
|
+
expect(conf).to receive(:load_file).and_return({})
|
24
|
+
expect(YAMG.new.setup_for(true)).to eq('path' => './media')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/yamg.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yamg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcos Piccinini
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mini_magick
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: screencap
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rainbow
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -57,7 +71,15 @@ files:
|
|
57
71
|
- Rakefile
|
58
72
|
- bin/yamg
|
59
73
|
- lib/yamg.rb
|
74
|
+
- lib/yamg/cli.rb
|
75
|
+
- lib/yamg/icon.rb
|
76
|
+
- lib/yamg/screenshot.rb
|
77
|
+
- lib/yamg/splash.rb
|
78
|
+
- lib/yamg/templates.yaml
|
60
79
|
- lib/yamg/version.rb
|
80
|
+
- lib/yamg/yamg.yml
|
81
|
+
- spec/spec_helper.rb
|
82
|
+
- spec/yamg/yamg_spec.rb
|
61
83
|
- yamg.gemspec
|
62
84
|
homepage: http://github.com/nofxx/yamg
|
63
85
|
licenses:
|
@@ -83,4 +105,6 @@ rubygems_version: 2.4.7
|
|
83
105
|
signing_key:
|
84
106
|
specification_version: 4
|
85
107
|
summary: Yet another media generator
|
86
|
-
test_files:
|
108
|
+
test_files:
|
109
|
+
- spec/spec_helper.rb
|
110
|
+
- spec/yamg/yamg_spec.rb
|