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.
@@ -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: