asset_compiler 0.2
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/lib/asset_compiler.rb +26 -0
- data/lib/asset_compiler/asset_task.rb +168 -0
- data/lib/asset_compiler/image_task.rb +39 -0
- data/lib/asset_compiler/rmagick_transformation_script.rb +156 -0
- metadata +53 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
$: << File.join( File.dirname( __FILE__ ), 'asset_compiler' )
|
2
|
+
|
3
|
+
require 'rubygems' unless $".include? 'rubygems.rb'
|
4
|
+
require 'asset_task'
|
5
|
+
require 'image_task'
|
6
|
+
|
7
|
+
# Convenience method to define an AssetTask in the assets namespace.
|
8
|
+
def asset_task name, &block
|
9
|
+
namespace :assets do
|
10
|
+
AssetTask.new name, &block
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Convenience method to define an ImageTask in the assets namespace.
|
15
|
+
def image_task name, &block
|
16
|
+
namespace :assets do
|
17
|
+
ImageTask.new name, &block
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Convenience method to add transformations to RMagickTransformationScript
|
22
|
+
def define_image_transformation name, &block
|
23
|
+
RMagickTransformationScript.class_eval do
|
24
|
+
define_method name, &block
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
#--
|
2
|
+
# Jeremy Voorhis
|
3
|
+
# March 2006
|
4
|
+
#++
|
5
|
+
|
6
|
+
# Task library for managing a directory of assets.
|
7
|
+
# For example:
|
8
|
+
#
|
9
|
+
# namespace :assets do
|
10
|
+
# AssetTask.new( :old_war_films ) do |t|
|
11
|
+
# t.src_files = Rake::FileList[image_src 'old_war_films/*.mov']
|
12
|
+
# t.build_path = File.join RAILS_ROOT, 'public/assets/old_war_films'
|
13
|
+
#
|
14
|
+
# t.transformation do |src, target|
|
15
|
+
# cp src, target
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# This example defines the following tasks:
|
21
|
+
# rake assets:build # Build all assets
|
22
|
+
# rake assets:clobber # Clobber all assets
|
23
|
+
# rake assets:old_war_films:build # Build the old_war_films files
|
24
|
+
# rake assets:old_war_films:clobber # Remove old_war_films files
|
25
|
+
# rake assets:old_war_films:rebuild # Force a rebuild of the old_war_films files
|
26
|
+
# rake assets:rebuild # Rebuild all assets
|
27
|
+
|
28
|
+
require 'rake/tasklib'
|
29
|
+
|
30
|
+
class AssetTask
|
31
|
+
attr_accessor :name
|
32
|
+
attr_accessor :src_files
|
33
|
+
attr_accessor :build_path
|
34
|
+
attr_accessor :remote_dirs
|
35
|
+
|
36
|
+
def initialize name, &block
|
37
|
+
@name = name
|
38
|
+
@src_files = Rake::FileList.new
|
39
|
+
@remote_dirs = []
|
40
|
+
|
41
|
+
instance_eval &block
|
42
|
+
|
43
|
+
define_clobber
|
44
|
+
define_rebuild
|
45
|
+
define_build_directory_task
|
46
|
+
define_build_task
|
47
|
+
add_dependencies_to_main_task
|
48
|
+
end
|
49
|
+
|
50
|
+
def from path
|
51
|
+
@src_files = path
|
52
|
+
end
|
53
|
+
|
54
|
+
def to path
|
55
|
+
@build_path = path
|
56
|
+
end
|
57
|
+
|
58
|
+
# Captures the transformation run on each individual object.
|
59
|
+
def transformation
|
60
|
+
@transformation = Proc.new
|
61
|
+
end
|
62
|
+
|
63
|
+
protected
|
64
|
+
# Returns an absolute target path for a given absolute +src+ path.
|
65
|
+
def target_for src
|
66
|
+
File.join @build_path, File.basename( src )
|
67
|
+
end
|
68
|
+
|
69
|
+
# Name of the build task for this task library.
|
70
|
+
def build_task_name
|
71
|
+
"#{@name}:build"
|
72
|
+
end
|
73
|
+
|
74
|
+
# Name of the clobber task for this task library.
|
75
|
+
def clobber_task_name
|
76
|
+
"#{@name}:clobber"
|
77
|
+
end
|
78
|
+
|
79
|
+
# Name of the rebuild task for this task library.
|
80
|
+
def rebuild_task_name
|
81
|
+
"#{@name}:rebuild"
|
82
|
+
end
|
83
|
+
|
84
|
+
# Defines the rebuild task for this task library.
|
85
|
+
def define_rebuild
|
86
|
+
desc "Force a rebuild of the #{@name} files"
|
87
|
+
task rebuild_task_name => [clobber_task_name, build_task_name]
|
88
|
+
end
|
89
|
+
|
90
|
+
# Defines the clobber task for this task library.
|
91
|
+
def define_clobber
|
92
|
+
desc "Remove #{@name} files"
|
93
|
+
task clobber_task_name do
|
94
|
+
rm_r @build_path rescue nil
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Defines the task which creates the build directory if it does not exist.
|
99
|
+
# Automatically a dependency of the task lib's build task.
|
100
|
+
def define_build_directory_task
|
101
|
+
directory @build_path
|
102
|
+
task build_task_name => @build_path
|
103
|
+
end
|
104
|
+
|
105
|
+
# Defines the main build task for this task library.
|
106
|
+
def define_build_task
|
107
|
+
desc "Build the #{@name} files"
|
108
|
+
task build_task_name
|
109
|
+
|
110
|
+
@src_files.each do |src|
|
111
|
+
# Figure our target
|
112
|
+
target = target_for src
|
113
|
+
|
114
|
+
# Process each file
|
115
|
+
file target => [src, @build_path] do
|
116
|
+
do_transformation src, target
|
117
|
+
do_transfer target
|
118
|
+
end
|
119
|
+
|
120
|
+
# Add target as a dependency
|
121
|
+
task build_task_name => target
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Adds dependencies for main asset-related tasks in this namespace
|
126
|
+
def add_dependencies_to_main_task
|
127
|
+
desc 'Build all assets' unless task( :build ).comment
|
128
|
+
task :build => build_task_name
|
129
|
+
|
130
|
+
desc 'Clobber all assets' unless task( :clobber ).comment
|
131
|
+
task :clobber => [clobber_task_name]
|
132
|
+
|
133
|
+
desc 'Rebuild all assets' unless task( :rebuild ).comment
|
134
|
+
task :rebuild => [clobber_task_name, build_task_name]
|
135
|
+
end
|
136
|
+
|
137
|
+
protected
|
138
|
+
# Transform a file based on a previously captured block where +src+ is the path to a source file
|
139
|
+
# and +target+ is the build task's target file. Dependent tasks may expect +target+ to exist.
|
140
|
+
def do_transformation src, target
|
141
|
+
@transformation.call src, target
|
142
|
+
end
|
143
|
+
|
144
|
+
# Transfer a file to a remote directory. Supports multiple file transports.
|
145
|
+
def do_transfer target
|
146
|
+
unless @remote_dirs.empty? || ENV['TRANSFER'] == 'no'
|
147
|
+
raise "File #{target} not found!" unless File.exist? target
|
148
|
+
|
149
|
+
@remote_dirs.each do |dir|
|
150
|
+
case dir[:transport]
|
151
|
+
when :ftp
|
152
|
+
do_ftp dir[:host], dir[:user], dir[:password], dir[:path], target
|
153
|
+
when :ssh
|
154
|
+
# TODO: implement me!
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Transport a file to a remote directory via FTP.
|
161
|
+
def do_ftp host, user, pwd, path, file
|
162
|
+
require 'net/ftp'
|
163
|
+
Net::FTP.open host, user, pwd do |ftp|
|
164
|
+
ftp.chdir path
|
165
|
+
ftp.putbinaryfile file
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#--
|
2
|
+
# Jeremy Voorhis
|
3
|
+
# March 2006
|
4
|
+
#++
|
5
|
+
|
6
|
+
require 'rmagick_transformation_script'
|
7
|
+
|
8
|
+
# Task library for managing a directory of images.
|
9
|
+
#
|
10
|
+
# For example:
|
11
|
+
# namespace :assets do
|
12
|
+
# ImageTask.new( :navigation_icons ) do |t|
|
13
|
+
# t.src_files = Rake::FileList[image_src 'navigation_icons/*.jpg']
|
14
|
+
# t.build_path = File.join RAILS_ROOT, 'public/assets/navigation_icons'
|
15
|
+
#
|
16
|
+
# t.transformation do |img|
|
17
|
+
# img.greyscale
|
18
|
+
# img.size_to_fit '64x64'
|
19
|
+
# img.icc_profile icc_profile_path
|
20
|
+
# img.icm_profile icm_profile_path
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# This example defines the following tasks:
|
26
|
+
# rake assets:build # Build all assets
|
27
|
+
# rake assets:clobber # Clobber all assets
|
28
|
+
# rake assets:navigation_icons:build # Build the navigation_icons files
|
29
|
+
# rake assets:navigation_icons:clobber # Remove navigation_icons files
|
30
|
+
# rake assets:navigation_icons:rebuild # Force a rebuild of the navigation_icons files
|
31
|
+
# rake assets:rebuild # Rebuild all assets
|
32
|
+
class ImageTask < AssetTask
|
33
|
+
|
34
|
+
protected
|
35
|
+
def do_transformation src, target
|
36
|
+
transformation_script = RMagickTransformationScript.new src, &@transformation
|
37
|
+
transformation_script.write target
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'RMagick'
|
2
|
+
|
3
|
+
# Holds a reference to an instance of <tt>Magick::Image</tt> and manages operations on it. Used
|
4
|
+
# to provide a more consistent, higher-level api than is given by RMagick.
|
5
|
+
#
|
6
|
+
# +ImageTransformationScript+ automatically invokes Ruby's garbage collector by calling <tt>GC.start</tt>
|
7
|
+
# upon instantiating a Magick::Image object. To bypass this, set the +GC+ environment variable to 'no'.
|
8
|
+
class RMagickTransformationScript
|
9
|
+
|
10
|
+
GRAVITY_TYPES = {
|
11
|
+
:none => Magick::ForgetGravity,
|
12
|
+
:northwest => Magick::NorthWestGravity,
|
13
|
+
:north => Magick::NorthGravity,
|
14
|
+
:northeast => Magick::NorthEastGravity,
|
15
|
+
:west => Magick::WestGravity,
|
16
|
+
:center => Magick::CenterGravity,
|
17
|
+
:east => Magick::EastGravity,
|
18
|
+
:southwest => Magick::SouthWestGravity,
|
19
|
+
:south => Magick::SouthGravity,
|
20
|
+
:southeast => Magick::SouthEastGravity
|
21
|
+
}
|
22
|
+
|
23
|
+
# Initialize an <tt>ImageTransformationScript</tt> where +img+ is either a path to an image or
|
24
|
+
# an instance of <tt>Magick::Image</tt>.
|
25
|
+
def initialize img, &block
|
26
|
+
@image = img if img.is_a? Magick::Image
|
27
|
+
@image = read img if img.is_a? String
|
28
|
+
raise ArgumentError.new( 'img must be either a path to an image or a Magick::Image object' ) \
|
29
|
+
unless @image
|
30
|
+
|
31
|
+
instance_eval &block
|
32
|
+
|
33
|
+
GC.start unless ENV['GC'] == 'no'
|
34
|
+
end
|
35
|
+
|
36
|
+
# Read an image from a file specified by +src+ and return a <tt>Magick::Image</tt> instance.
|
37
|
+
def read src
|
38
|
+
Magick::Image.read( src ).first
|
39
|
+
end
|
40
|
+
|
41
|
+
# Write the image to a specified path, <tt>target</tt>.
|
42
|
+
def write target
|
43
|
+
@image.write target do
|
44
|
+
quality = 95
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Tints the image according to the following parameters:
|
49
|
+
# * <tt>r</tt> Blending factor for the red channel
|
50
|
+
# * <tt>g</tt> Blending factor for the green channel
|
51
|
+
# * <tt>b</tt> Blending factor for the blue channel
|
52
|
+
# * <tt>overlay</tt> Color to tint the image
|
53
|
+
# img.tint 0.25, 0.25, 0.25, #ffffff # lightens the image 25%
|
54
|
+
def tint r, g, b, overlay
|
55
|
+
@image = @image.colorize r, g, b, overlay
|
56
|
+
@image
|
57
|
+
end
|
58
|
+
|
59
|
+
# Sharpen only the edges of the image. Parameters are:
|
60
|
+
# * <tt>rad</tt> Radius: how big an edge can be
|
61
|
+
# * <tt>sig</tt> Sigma weight for gaussian: leave it at 1.0.
|
62
|
+
# * <tt>blend</tt> Blending factor: how much sharpening to apply as a percentage
|
63
|
+
# * <tt>thresh</tt> Threshold: how different 2 pixels must be to qualify as an edge
|
64
|
+
# img.unsharp_mask 0.5, 1.0, 0.5, 0.25
|
65
|
+
def unsharp_mask rad = 0.5, sig = 1.0, blend = 0.5, thresh = 0.25
|
66
|
+
@image = @image.unsharp_mask rad, sig, blend, thresh
|
67
|
+
@image
|
68
|
+
end
|
69
|
+
|
70
|
+
# Lightens the image. Defaults to a blend factor of 25%.
|
71
|
+
# img.lighten # lightens the image 25%.
|
72
|
+
# img.lighten 0.40 # lightens the image 40%.
|
73
|
+
def lighten factor = 0.25
|
74
|
+
tint factor, factor, factor, '#ffffff'
|
75
|
+
end
|
76
|
+
|
77
|
+
# Darkens the image. Defaults to a blend factor of 25%.
|
78
|
+
# img.darken # darkens the image 25%.
|
79
|
+
# img.darken 0.40 # darkens the image 40%.
|
80
|
+
def darken factor = 0.25
|
81
|
+
tint factor, factor, factor, '#000000'
|
82
|
+
end
|
83
|
+
|
84
|
+
# Converts the image to greyscale.
|
85
|
+
# img.greyscale # uses default overlay of #aa9955.
|
86
|
+
# img.greyscale '#aaaaaa' # uses specified overlay.
|
87
|
+
def greyscale overlay = '#aa9955'
|
88
|
+
@image = @image.quantize 256, Magick::GRAYColorspace
|
89
|
+
tint 0.25, 0.25, 0.25, overlay
|
90
|
+
@image
|
91
|
+
end
|
92
|
+
|
93
|
+
# Resizes the image to fit within the constraints specified by +dimensions+ where +dimensions+ is
|
94
|
+
# a +String+ in the format of 'WIDTHxLENGTH'.
|
95
|
+
# img.size_to_fit '64x64'
|
96
|
+
def size_to_fit dimensions
|
97
|
+
@image.change_geometry dimensions do |w,h,img|
|
98
|
+
img.density = '72x72'
|
99
|
+
img.resize! w, h
|
100
|
+
# radius, sigma, blend, threshold
|
101
|
+
unsharp_mask 0.5, 1.0, 0.5, 0.25
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Resizes the image proportionally to fit the smaller dimension, then crops excess.
|
106
|
+
# Optionally, a gravity setting may be provided. From the RMagick docs:
|
107
|
+
#
|
108
|
+
# Gravity provides a convenient way to locate objects irrespective of the size of the
|
109
|
+
# bounding region, in other words, you don't need to provide absolute coordinates in
|
110
|
+
# order to position an object.
|
111
|
+
#
|
112
|
+
# The default gravity setting is <tt>:center</tt>. Available settings are:
|
113
|
+
# [<tt>:none</tt>] don't use gravity
|
114
|
+
# [<tt>:northwest</tt>] crop to northwest
|
115
|
+
# [<tt>:north</tt>] crop to north - good for vertical images
|
116
|
+
# [<tt>:northeast</tt>] crop to northeast
|
117
|
+
# [<tt>:west</tt>] crop to west
|
118
|
+
# [<tt>:center</tt>] crop to center - default
|
119
|
+
# [<tt>:east</tt>] crop to east
|
120
|
+
# [<tt>:southwest</tt>] crop to southwest
|
121
|
+
# [<tt>:south</tt>] crop to south
|
122
|
+
# [<tt>:southeast</tt>] crop to southeast
|
123
|
+
#
|
124
|
+
# Usage:
|
125
|
+
# img.crop_to '64x64' # crops to center, 64x64 pixels
|
126
|
+
# img.crop_to '64x64', :north # crops to north - common for thumbnailing portraits
|
127
|
+
def crop_to size_string, gravity = :center
|
128
|
+
width, height = size_string.scan( /\d+/ ).collect { |i| i.to_i }
|
129
|
+
max = ( width > height ? width : height )
|
130
|
+
aspect = @image.columns.to_f / @image.rows.to_f
|
131
|
+
@image.resize!( max, ( max / aspect ).to_i ) if aspect < 1.0
|
132
|
+
@image.resize!( (max*aspect).to_i, max ) unless aspect < 1.0
|
133
|
+
# radius, sigma, blend, threshold
|
134
|
+
unsharp_mask 0.5, 1.0, 0.5, 0.25
|
135
|
+
@image.crop!( GRAVITY_TYPES[gravity], width, height )
|
136
|
+
@image
|
137
|
+
end
|
138
|
+
|
139
|
+
# Applies an ICC profile to the image. Requires +path+ which is a path to a file containing
|
140
|
+
# a valid ICC profile.
|
141
|
+
# img.icc_profile 'srgb.icc'
|
142
|
+
def icc_profile path
|
143
|
+
profile = File.open( path ).readlines.join( '' ) if File.exist? path
|
144
|
+
@image.profile! 'ICC', profile if profile
|
145
|
+
@image
|
146
|
+
end
|
147
|
+
|
148
|
+
# Applies an ICM profile to the image. Requires +path+ which is a path to a file containing
|
149
|
+
# a valid ICM profile.
|
150
|
+
# img.icm_profile 'srgb.icm'
|
151
|
+
def icm_profile path
|
152
|
+
profile = File.open( path ).readlines.join('') if File.exist? path
|
153
|
+
@image.profile! 'ICM', profile if profile
|
154
|
+
@image
|
155
|
+
end
|
156
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.10
|
3
|
+
specification_version: 1
|
4
|
+
name: asset_compiler
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "0.2"
|
7
|
+
date: 2006-05-08
|
8
|
+
summary: Rake task libraries for managing assets. Especially images.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: jeremy@planetargon.com
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description: "Asset Compiler is a collection of Rake task libraries to lighten the load of
|
15
|
+
asset management. These libraries allow you to manage local assets, manipulate
|
16
|
+
images and transport assets to a remote server."
|
17
|
+
autorequire: asset_compiler
|
18
|
+
default_executable:
|
19
|
+
bindir: bin
|
20
|
+
has_rdoc: true
|
21
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
22
|
+
requirements:
|
23
|
+
-
|
24
|
+
- ">"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.0.0
|
27
|
+
version:
|
28
|
+
platform: ruby
|
29
|
+
authors:
|
30
|
+
- Jeremy Voorhis
|
31
|
+
files:
|
32
|
+
- lib/asset_compiler.rb
|
33
|
+
- lib/asset_compiler/asset_task.rb
|
34
|
+
- lib/asset_compiler/image_task.rb
|
35
|
+
- lib/asset_compiler/rmagick_transformation_script.rb
|
36
|
+
test_files: []
|
37
|
+
rdoc_options: []
|
38
|
+
extra_rdoc_files: []
|
39
|
+
executables: []
|
40
|
+
extensions: []
|
41
|
+
requirements:
|
42
|
+
- "RMagick, built with lcms"
|
43
|
+
dependencies:
|
44
|
+
- !ruby/object:Gem::Dependency
|
45
|
+
name: rake
|
46
|
+
version_requirement:
|
47
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
48
|
+
requirements:
|
49
|
+
-
|
50
|
+
- ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.7.0
|
53
|
+
version:
|