class ImageOptim
Main interface
Attributes
Allow lossy workers and optimizations
Cache
directory
Cache
worker digests
Nice level
Use image_optim_pack
Skip workers with missing or problematic binaries
Number of threads to run with
Timeout
Verbose output?
Public Class Methods
Full version of image_optim
# File lib/image_optim.rb, line 216 def full_version "image_optim v#{version}" end
Optimization methods with default options
# File lib/image_optim.rb, line 190 def method_missing(method, *args, &block) if optimize_image_method?(method) new.send(method, *args, &block) else super end end
Initialize workers, specify options using worker underscored name:
pass false to disable worker
ImageOptim.new(:pngcrush => false)
or hash with options to worker
ImageOptim.new(:advpng => {:level => 3}, :optipng => {:level => 2})
use :threads to set number of parallel optimizers to run (passing true or nil determines number of processors, false disables parallel processing)
ImageOptim.new(:threads => 8)
use :nice to specify optimizers nice level (true or nil makes it 10, false makes it 0)
ImageOptim.new(:nice => 20)
# File lib/image_optim.rb, line 71 def initialize(options = {}) config = Config.new(options) @verbose = config.verbose $stderr << "config:\n#{config.to_s.gsub(/^/, ' ')}" if verbose %w[ nice threads pack skip_missing_workers allow_lossy cache_dir cache_worker_digests timeout ].each do |name| instance_variable_set(:"@#{name}", config.send(name)) $stderr << "#{name}: #{send(name)}\n" if verbose end @bin_resolver = BinResolver.new(self) @workers_by_format = Worker.create_all_by_format(self) do |klass| config.for_worker(klass) end @cache = Cache.new(self, @workers_by_format) log_workers_by_format if verbose config.assert_no_unused_options! end
# File lib/image_optim.rb, line 203 def respond_to?(method, include_private = false) optimize_image_method?(method) || super end
# File lib/image_optim.rb, line 198 def respond_to_missing?(method, include_private = false) optimize_image_method?(method) || super end
Version of image_optim gem spec loaded
# File lib/image_optim.rb, line 209 def version Gem.loaded_specs['image_optim'].version.to_s rescue 'DEV' end
Private Class Methods
# File lib/image_optim.rb, line 222 def optimize_image_method?(method) method_defined?(method) && method.to_s =~ /^optimize_image/ end
Public Instance Methods
Join resolve_dir, default path and vendor path for PATH environment variable
# File lib/image_optim.rb, line 239 def env_path @bin_resolver.env_path end
Are there workers for file at path?
# File lib/image_optim.rb, line 228 def optimizable?(path) !!workers_for_image(path) end
Optimize one file, return new path as OptimizedPath
or nil if optimization failed
# File lib/image_optim.rb, line 110 def optimize_image(original) original = Path.convert(original) return unless (workers = workers_for_image(original)) optimized = @cache.fetch(original) do Handler.for(original) do |handler| current_worker = nil begin with_timeout(@timeout) do workers.each do |worker| current_worker = worker handler.process{ |src, dst| worker.optimize(src, dst) } end end rescue TimeoutExceeded => e if current_worker && current_worker.pid pid = current_worker.pid cleanup_process(pid) end raise e end end end return unless optimized OptimizedPath.new(optimized, original) end
Optimize one file in place, return original as OptimizedPath
or nil if optimization failed
# File lib/image_optim.rb, line 142 def optimize_image!(original) original = Path.convert(original) return unless (result = optimize_image(original)) result.replace(original) OptimizedPath.new(original, result.original_size) end
Optimize image data, return new data or nil if optimization failed
# File lib/image_optim.rb, line 150 def optimize_image_data(original_data) format = ImageMeta.format_for_data(original_data) return unless format Path.temp_file %W[image_optim .#{format}] do |temp| temp.binmode temp.write(original_data) temp.close if (result = optimize_image(temp.path)) result.binread end end end
Optimize multiple images if block given yields path and result for each image and returns array of yield results else return array of path and result pairs
# File lib/image_optim.rb, line 168 def optimize_images(paths, &block) run_method_for(paths, :optimize_image, &block) end
Optimize multiple images in place if block given yields path and result for each image and returns array of yield results else return array of path and result pairs
# File lib/image_optim.rb, line 176 def optimize_images!(paths, &block) run_method_for(paths, :optimize_image!, &block) end
Optimize multiple image datas if block given yields original and result for each image data and returns array of yield results else return array of path and result pairs
# File lib/image_optim.rb, line 184 def optimize_images_data(datas, &block) run_method_for(datas, :optimize_image_data, &block) end
Check existance of binary, create symlink if ENV contains path for key XXX_BIN where XXX is upper case bin name
# File lib/image_optim.rb, line 234 def resolve_bin!(bin) @bin_resolver.resolve!(bin) end
Get workers for image
# File lib/image_optim.rb, line 104 def workers_for_image(path) @workers_by_format[Path.convert(path).image_format] end
Private Instance Methods
Apply threading if threading is allowed
# File lib/image_optim.rb, line 305 def apply_threading(enum) if threads > 1 enum.in_threads(threads) else enum end end
# File lib/image_optim.rb, line 257 def cleanup_process(pid) Process.detach(pid) Process.kill('-TERM', pid) now = Time.now while Time.now - now < 10 begin Process.getpgid(pid) sleep 0.1 rescue Errno::ESRCH break end end Process.kill('-KILL', pid) if Process.getpgid(pid) rescue Errno::ESRCH pid end
# File lib/image_optim.rb, line 276 def log_workers_by_format $stderr << "Workers by format:\n" @workers_by_format.each do |format, workers| $stderr << "#{format}:\n" workers.each do |worker| $stderr << " #{worker.class.bin_sym}:\n" worker.options.each do |name, value| $stderr << " #{name}: #{value.inspect}\n" end end end end
Run method for each item in list if block given yields item and result for item and returns array of yield results else return array of item and result pairs
# File lib/image_optim.rb, line 293 def run_method_for(list, method_name, &block) apply_threading(list).map do |item| result = send(method_name, item) if block yield item, result else [item, result] end end end
# File lib/image_optim.rb, line 245 def with_timeout(timeout) if timeout && timeout >= 0 thread = Thread.new{ yield if block_given? } if thread.respond_to?(:report_on_exception) thread.report_on_exception = false end fail TimeoutExceeded if thread.join(timeout).nil? elsif block_given? yield end end