XCUtils 0.1.1 → 0.2.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 +4 -4
- data/bin/xcutils +17 -0
- data/lib/XCUtils/version.rb +1 -1
- data/lib/XCUtils/xcutils_resize.rb +140 -0
- data/lib/XCUtils/xcutils_sorter.rb +1 -1
- metadata +23 -10
- data/bin/xcatlasify +0 -45
- data/lib/XCUtils/xcutils_patcher.rb +0 -48
- data/lib/XCUtils/xcutils_resizer.rb +0 -65
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb1a1a45c660b01ad9672329aabcf7b8ac5ff491
|
4
|
+
data.tar.gz: f6e3b8f7fb21070693a6cb8d803b8bab0a19f335
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d8c10c8ee75d7a46f19a6ce254ce1c00fe2ce01acce741c6c7e16c5bef2781baebf6c7c171cbb076238d57bf0e9d874c109600ea8737ce790e6f72f52a09c51
|
7
|
+
data.tar.gz: a4b2c57213075d1a1840942ab5857fae13a88618baa613d84264225959fe85c38d893de30ef6b0fc3f6f2f149c39cdf6be3935753fbb2646bc141284c57b3567
|
data/bin/xcutils
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require "XCUtils/version"
|
4
|
+
require 'rubygems'
|
5
|
+
|
6
|
+
require "thor"
|
7
|
+
require_relative "../lib/XCUtils/xcutils_resize"
|
8
|
+
require_relative "../lib/XCUtils/xcutils_sorter"
|
9
|
+
|
10
|
+
class XCUtil < Thor
|
11
|
+
|
12
|
+
register(XCUtils::XCUtilsSorter, "sort", "sort", "sort directory of all sizes artwork into separate image atlases per size")
|
13
|
+
register(XCUtils::XCUtilsResize, "resize", "resize", "resize single image or directory to all available sizes and pack into xcassets folder")
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
XCUtil.start
|
data/lib/XCUtils/version.rb
CHANGED
@@ -0,0 +1,140 @@
|
|
1
|
+
require "thor"
|
2
|
+
require 'fileutils'
|
3
|
+
require 'debugger'
|
4
|
+
require 'json'
|
5
|
+
require 'parseconfig'
|
6
|
+
require 'RMagick'
|
7
|
+
require "XCUtils/xcutils_image"
|
8
|
+
|
9
|
+
module XCUtils
|
10
|
+
class XCUtilsResize < Thor::Group
|
11
|
+
include Thor::Actions
|
12
|
+
|
13
|
+
@options_merge = {}
|
14
|
+
|
15
|
+
argument :source, desc: "source directory or file"
|
16
|
+
argument :target, desc: "target directory or file"
|
17
|
+
|
18
|
+
class_options :scale_iphone_1x => 0.25, desc: "Iphone 3 scale"
|
19
|
+
class_options :scale_iphone_2x => 0.5, desc: "Iphone @2x scale"
|
20
|
+
class_options :scale_iphone_3x => 1.0, desc: "Iphone @3x scale"
|
21
|
+
class_options :scale_ipad_1x => 0.5, desc: "IPad scale"
|
22
|
+
class_options :scale_ipad_2x => 1.0, desc: "IPad @2x scale - source scale"
|
23
|
+
|
24
|
+
class_options :create_image_assets => false, desc: "create xcassets folder per image including json, default: false"
|
25
|
+
class_options :create_xcatlas => false, desc: "create xcatlas for folder, default: false"
|
26
|
+
class_options :dry_run => false, desc: "print only logs - no files are created, default: false"
|
27
|
+
|
28
|
+
def check_configuration_file
|
29
|
+
|
30
|
+
# check for configuration file
|
31
|
+
config_path = File.join(source,".xcutils-config")
|
32
|
+
|
33
|
+
if File.exists?(config_path)
|
34
|
+
original_options = options
|
35
|
+
say "found configuration file", nil
|
36
|
+
defaults = ParseConfig.new(config_path).params || {}
|
37
|
+
defaults = defaults.map{ |key,value| {key => value.to_f} }.reduce(:merge)
|
38
|
+
@options_merge = original_options.merge( defaults )
|
39
|
+
end
|
40
|
+
|
41
|
+
# print current configuration
|
42
|
+
say_status "iphone 1x scale", @options_merge[:scale_iphone_1x], :blue
|
43
|
+
say_status "iphone 2x scale", @options_merge[:scale_iphone_2x], :blue
|
44
|
+
say_status "iphone 3x scale", @options_merge[:scale_iphone_3x], :blue
|
45
|
+
say_status "ipad 1x scale", @options_merge[:scale_ipad_1x], :blue
|
46
|
+
say_status "ipad 2x scale", @options_merge[:scale_ipad_2x], :blue
|
47
|
+
say_status "create image assets:", @options_merge[:create_image_assets], :blue
|
48
|
+
say_status "create xcatlas:", @options_merge[:create_xcatlas], :blue
|
49
|
+
|
50
|
+
say_status "DRY RUN - no files will be created!", nil, :red if @options_merge[:dry_run]
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
def create_output_directory
|
55
|
+
say_status "create output directory", nil, :yellow
|
56
|
+
name = File.basename target
|
57
|
+
Dir.mkdir(target) unless Dir.exists?(target)
|
58
|
+
end
|
59
|
+
|
60
|
+
def xcassets_directory
|
61
|
+
|
62
|
+
# support single file or directory source
|
63
|
+
source_elements = File.directory?(source) ? Dir.entries(source) : [ File.basename(source) ]
|
64
|
+
|
65
|
+
# each source file
|
66
|
+
source_elements.each do |f|
|
67
|
+
|
68
|
+
next if f == "." || f == ".." || f == ".DS_Store" || f == ".xcutils-config"
|
69
|
+
|
70
|
+
fn = f.gsub("@3x","").gsub("~ipad","").gsub("@2x","") # remove extensions
|
71
|
+
fn = File.basename(fn,File.extname(fn)) # remove file extension
|
72
|
+
|
73
|
+
say_status "# #{fn}", nil, :magenta
|
74
|
+
|
75
|
+
# create folder
|
76
|
+
base_name = File.basename(target)
|
77
|
+
imageset_folder = @options_merge[:create_image_assets] ? File.join(target,"#{fn}.imageset") : target
|
78
|
+
imageset_folder = File.join(target,"#{base_name}.atlas") if @options_merge[:create_xcatlas]
|
79
|
+
Dir.mkdir(imageset_folder) unless Dir.exists?(imageset_folder)
|
80
|
+
|
81
|
+
say_status "packing into xcasset:", imageset_folder, :blue if @options_merge[:create_image_assets]
|
82
|
+
say_status "packing into xcatlas:", imageset_folder, :blue if @options_merge[:create_xcatlas]
|
83
|
+
|
84
|
+
# load image
|
85
|
+
img = Magick::Image.read(File.join(source,f)).first
|
86
|
+
|
87
|
+
# create @3x version
|
88
|
+
say_status "create @3x version", "#{fn}@3x", :yellow
|
89
|
+
unless @options_merge[:dry_run]
|
90
|
+
img_3x = XCUtilsImage.scale_image(img,@options_merge[:scale_iphone_3x])
|
91
|
+
img_3x.write(File.join(imageset_folder,"#{fn}@3x.png"))
|
92
|
+
end
|
93
|
+
content_iphone_3x = {"idiom" => "iphone", "scale" => "3x", "filename" => "#{fn}@3x.png"}
|
94
|
+
|
95
|
+
# create ipad retina version
|
96
|
+
say_status "create ipad retina version", "#{fn}@2x~ipad", :yellow
|
97
|
+
unless @options_merge[:dry_run]
|
98
|
+
img_ipad_2x = XCUtilsImage.scale_image(img,@options_merge[:scale_ipad_2x])
|
99
|
+
img_ipad_2x.write(File.join(imageset_folder,"#{fn}@2x~ipad.png"))
|
100
|
+
end
|
101
|
+
content_ipad_2x = {"idiom" => "ipad", "scale" => "2x", "filename" => "#{fn}@2x~ipad.png"}
|
102
|
+
|
103
|
+
# create ipad non retina version
|
104
|
+
say_status "create ipad non retina version", "#{fn}~ipad", :yellow
|
105
|
+
unless @options_merge[:dry_run]
|
106
|
+
img_ipad_1x = XCUtilsImage.scale_image(img,@options_merge[:scale_ipad_1x])
|
107
|
+
img_ipad_1x.write(File.join(imageset_folder,"#{fn}~ipad.png"))
|
108
|
+
end
|
109
|
+
content_ipad = {"idiom" => "ipad", "scale" => "1x", "filename" => "#{fn}~ipad.png"}
|
110
|
+
|
111
|
+
# create iphone retina version
|
112
|
+
say_status "create iphone retina version", "#{fn}@2x", :yellow
|
113
|
+
unless @options_merge[:dry_run]
|
114
|
+
img_iphone_2x = XCUtilsImage.scale_image(img,@options_merge[:scale_iphone_2x])
|
115
|
+
img_iphone_2x.write(File.join(imageset_folder,"#{fn}@2x.png"))
|
116
|
+
end
|
117
|
+
content_iphone_2x = {"idiom" => "iphone", "scale" => "2x", "filename" => "#{fn}@2x.png"}
|
118
|
+
|
119
|
+
# create iphone non retina version
|
120
|
+
say_status "create iphone non retina version", "#{fn}", :yellow
|
121
|
+
unless @options_merge[:dry_run]
|
122
|
+
img_iphone_1x = XCUtilsImage.scale_image(img,@options_merge[:scale_iphone_1x])
|
123
|
+
img_iphone_1x.write(File.join(imageset_folder,"#{fn}.png"))
|
124
|
+
end
|
125
|
+
content_iphone = {"idiom" => "iphone", "scale" => "1x", "filename" => "#{fn}.png"}
|
126
|
+
|
127
|
+
# for imageassets create json
|
128
|
+
if @options_merge[:create_image_assets] && !@options_merge[:dry_run]
|
129
|
+
contents_json = JSON.pretty_generate( {"images" => [content_iphone, content_iphone_2x, content_iphone_3x, content_ipad, content_ipad_2x], "info" => {"version" => 1, "author" => "xcode"} } )
|
130
|
+
|
131
|
+
File.open(File.join(imageset_folder,"Contents.json"),"w") do |f|
|
132
|
+
f.write(contents_json)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: XCUtils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Müller
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-01-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -81,6 +81,20 @@ dependencies:
|
|
81
81
|
- - '>='
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: parseconfig
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
84
98
|
- !ruby/object:Gem::Dependency
|
85
99
|
name: debugger
|
86
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -97,20 +111,19 @@ dependencies:
|
|
97
111
|
version: '0'
|
98
112
|
description: |-
|
99
113
|
This is a little helper to resize @2x~ipad artwork to all required sizes using rmagick.
|
100
|
-
\x5On top, the output will be formatted to suit XCodes requirements for sprite atlases.
|
101
|
-
\x5Images will be resized carefully
|
114
|
+
\x5On top, the output will be formatted to suit XCodes requirements for sprite atlases or xcassets.
|
115
|
+
\x5Images will be resized carefully using 'HammingFilter'.
|
102
116
|
email:
|
103
117
|
- benjamin@urbn.de
|
104
118
|
- manolis@urbn.de
|
105
119
|
executables:
|
106
|
-
-
|
120
|
+
- xcutils
|
107
121
|
extensions: []
|
108
122
|
extra_rdoc_files: []
|
109
123
|
files:
|
110
|
-
- bin/
|
124
|
+
- bin/xcutils
|
111
125
|
- lib/XCUtils/version.rb
|
112
|
-
- lib/XCUtils/
|
113
|
-
- lib/XCUtils/xcutils_resizer.rb
|
126
|
+
- lib/XCUtils/xcutils_resize.rb
|
114
127
|
- lib/XCUtils/xcutils_sorter.rb
|
115
128
|
homepage: https://github.com/elchbenny/XCUtils
|
116
129
|
licenses:
|
@@ -132,8 +145,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
145
|
version: '0'
|
133
146
|
requirements: []
|
134
147
|
rubyforge_project:
|
135
|
-
rubygems_version: 2.4.
|
148
|
+
rubygems_version: 2.4.2
|
136
149
|
signing_key:
|
137
150
|
specification_version: 4
|
138
|
-
summary: Resize *.@2x~ipad named images and move em into XCodes atlases.
|
151
|
+
summary: Resize *.@2x~ipad named images and move em into XCodes atlases or xcassets.
|
139
152
|
test_files: []
|
data/bin/xcatlasify
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
#! /usr/bin/env ruby
|
2
|
-
|
3
|
-
require "XCUtils/version"
|
4
|
-
require 'rubygems'
|
5
|
-
|
6
|
-
require "thor"
|
7
|
-
require_relative "../lib/XCUtils/xcutils_resizer"
|
8
|
-
require_relative "../lib/XCUtils/xcutils_patcher"
|
9
|
-
|
10
|
-
class XCAtlasify < Thor
|
11
|
-
|
12
|
-
desc "resize [src-dir, tgt-dir]", "Resize *.@2x~ipad named images and move em into XCodes atlases."
|
13
|
-
long_desc <<-LONGDESC
|
14
|
-
This is a little helper to resize @2x~ipad artwork to all required sizes using rmagick.
|
15
|
-
\x5On top, the output will be formatted to suit XCodes requirements for sprite atlases.
|
16
|
-
\x5Images will be resized carefully by first extending images to be dividable by 4 and then generating smaller half and quarter resolutions.
|
17
|
-
LONGDESC
|
18
|
-
def resize(src, tgt)
|
19
|
-
validate_support
|
20
|
-
ARGV.shift
|
21
|
-
XCUtils::XCUtilsResizer.start
|
22
|
-
end
|
23
|
-
|
24
|
-
desc "sort", "This is a little helper to sort a directory containing normal, @2x, ~ipad, @2x~ipad artwork into 4 atlases."
|
25
|
-
def sort
|
26
|
-
validate_support
|
27
|
-
ARGV.shift
|
28
|
-
XCUtils::XCUtilsSorter.start
|
29
|
-
end
|
30
|
-
|
31
|
-
desc "patch [patch-vrs, base-atlas]", "This patches the current 'resize' result (directory structure) to the latest version"
|
32
|
-
def patch(vrs, base)
|
33
|
-
validate_support
|
34
|
-
ARGV.shift
|
35
|
-
XCUtils::XCUtilsPatcher.start
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
def validate_support
|
40
|
-
# check if the action is valid...
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
XCAtlasify.start
|
@@ -1,48 +0,0 @@
|
|
1
|
-
require "thor"
|
2
|
-
require 'fileutils'
|
3
|
-
require 'debugger'
|
4
|
-
|
5
|
-
module XCUtils
|
6
|
-
class XCUtilsPatcher < Thor::Group
|
7
|
-
include Thor::Actions
|
8
|
-
|
9
|
-
argument :version
|
10
|
-
argument :base
|
11
|
-
|
12
|
-
|
13
|
-
def rename_and_move
|
14
|
-
say_status "Patching", "version #{version}", :yellow
|
15
|
-
|
16
|
-
unless version.eql? "0.0.1"
|
17
|
-
say_status "Warning", "No patch for this version...", :red
|
18
|
-
abort
|
19
|
-
end
|
20
|
-
|
21
|
-
unless Dir.exists?("#{base}.atlas")
|
22
|
-
say_status "Warning", "The base atlas does not exist, make sure you are within the correct directoy", :red
|
23
|
-
abort
|
24
|
-
end
|
25
|
-
|
26
|
-
checkSuffix = ["~ipad", "@2x~ipad", "@2x"]
|
27
|
-
|
28
|
-
checkSuffix.each do |suffix|
|
29
|
-
dir_suffix = "#{base}#{suffix}.atlas"
|
30
|
-
|
31
|
-
say_status "Patching", "#{dir_suffix}", :yellow
|
32
|
-
Dir["#{dir_suffix}/*.png"].each do |f|
|
33
|
-
filename = File.basename(f, File.extname(f))
|
34
|
-
unless filename.eql? ("filename#{suffix}")
|
35
|
-
dir = File.dirname(f)
|
36
|
-
new_filename = "#{base}.atlas/#{filename}#{suffix}.png"
|
37
|
-
say_status "Moving", "#{f} :: #{new_filename}", :green
|
38
|
-
File.rename(f, new_filename)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
say_status "Deleting", "#{dir_suffix}", :yellow
|
42
|
-
FileUtils.rm_rf(dir_suffix)
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
require "thor"
|
2
|
-
require 'RMagick'
|
3
|
-
require 'fileutils'
|
4
|
-
require 'debugger'
|
5
|
-
|
6
|
-
module XCUtils
|
7
|
-
class XCUtilsResizer < Thor::Group
|
8
|
-
include Thor::Actions
|
9
|
-
|
10
|
-
argument :source
|
11
|
-
argument :target
|
12
|
-
|
13
|
-
def create_output_directory
|
14
|
-
say_status "create_output_directory", nil
|
15
|
-
name = File.basename target
|
16
|
-
Dir.mkdir(target) unless Dir.exists?(target)
|
17
|
-
Dir.mkdir(File.join(target,"#{name}.atlas")) unless Dir.exists?(File.join(target,"#{name}.atlas"))
|
18
|
-
end
|
19
|
-
|
20
|
-
def write_rename_images_to_dir
|
21
|
-
name = File.basename target
|
22
|
-
Dir.foreach(source) do |f|
|
23
|
-
next if f == "." || f == ".." || f == ".DS_Store"
|
24
|
-
|
25
|
-
if f.include?("@2x") && f.include?("~ipad")
|
26
|
-
|
27
|
-
fn = f.gsub("@2x","").gsub("~ipad","")
|
28
|
-
fn = File.basename(fn,File.extname(fn))
|
29
|
-
|
30
|
-
# load image
|
31
|
-
img = Magick::Image.read(File.join(source,f)).first
|
32
|
-
img.background_color = "none"
|
33
|
-
|
34
|
-
# adjust image size so it's devitable by 4
|
35
|
-
width = img.columns
|
36
|
-
height = img.rows
|
37
|
-
|
38
|
-
nWidth = width%4 == 0 ? width : (width + 4 - width%4)
|
39
|
-
nHeight = height%4 == 0 ? height : (height + 4 - height%4)
|
40
|
-
|
41
|
-
img = img.extent(nWidth, nHeight)
|
42
|
-
|
43
|
-
# create ipad retina version
|
44
|
-
say_status "create ipad retina version", "#{fn}@2x~ipad", :yellow
|
45
|
-
img.write(File.join(target,"#{name}.atlas","#{fn}@2x~ipad.png"))
|
46
|
-
|
47
|
-
# create ipad non retina version
|
48
|
-
say_status "create ipad non retina version", "#{fn}~ipad", :yellow
|
49
|
-
img.minify!
|
50
|
-
img.write(File.join(target,"#{name}.atlas","#{fn}~ipad.png"))
|
51
|
-
|
52
|
-
# create iphone retina version - identical to ipad non retina version
|
53
|
-
say_status "create iphone retina version - identical to ipad non retina version", "#{fn}@2x", :yellow
|
54
|
-
img.write(File.join(target,"#{name}.atlas","#{fn}@2x.png"))
|
55
|
-
|
56
|
-
# create iphone non retina version
|
57
|
-
say_status "create iphone non retina version", "#{fn}", :yellow
|
58
|
-
img.minify!
|
59
|
-
img.write(File.join(target,"#{name}.atlas","#{fn}.png"))
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
65
|
-
end
|