asset_compiler 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: