Class: ImageSqueeze

Inherits:
Object
  • Object
show all
Defined in:
lib/image_squeeze.rb,
lib/image_squeeze/utils.rb,
lib/image_squeeze/result.rb,
lib/image_squeeze/log_factory.rb,
lib/image_squeeze/image_identifier.rb,
lib/image_squeeze/processors/processor.rb,
lib/image_squeeze/processors/optipng_processor.rb,
lib/image_squeeze/processors/gifsicle_processor.rb,
lib/image_squeeze/processors/png_crush_processor.rb,
lib/image_squeeze/processors/gif_to_png_processor.rb,
lib/image_squeeze/processors/jpeg_tran_progressive_processor.rb,
lib/image_squeeze/processors/png_to_progressive_jpeg_processor.rb,
lib/image_squeeze/processors/jpeg_tran_non_progressive_processor.rb,
lib/image_squeeze/processors/png_to_non_progressive_jpeg_processor.rb

Defined Under Namespace

Modules: Utils Classes: GIFToPNGProcessor, GifsicleProcessor, JPEGTranNonProgressiveProcessor, JPEGTranProgressiveProcessor, LogFactory, OptiPNGProcessor, PNGCrushProcessor, PNGToNonProgressiveJPEGProcessor, PNGToProgressiveJPEGProcessor, Processor, Result

Constant Summary collapse

VERSION =
'0.1.5'
GIF =

Image Types

'gif'
ANIMATED_GIF =
'animated gif'
JPEG =
'jpeg'
PNG =
'png'
UNKNOWN =
'unknown'
NOT_FOUND =
'not_found'
IMAGE_TYPE_TO_EXTENSION =
{
  GIF => '.gif',
  ANIMATED_GIF => '.gif',
  JPEG => '.jpg',
  PNG => '.png'
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ ImageSqueeze

Returns a new instance of ImageSqueeze.



43
44
45
46
47
48
49
50
51
# File 'lib/image_squeeze.rb', line 43

def initialize(options = {})
  # identify is required
  ImageSqueeze::Utils.image_utility_available?('identify', 'all image', Logger::ERROR)
  
  @processors = options[:processors] || []
  @processors += self.class.default_processors if options[:default_processors]
  
  @tmpdir = options[:tmpdir] || Dir::tmpdir
end

Instance Attribute Details

#processorsObject (readonly)

Returns the value of attribute processors.



23
24
25
# File 'lib/image_squeeze.rb', line 23

def processors
  @processors
end

#tmpdirObject (readonly)

Returns the value of attribute tmpdir.



24
25
26
# File 'lib/image_squeeze.rb', line 24

def tmpdir
  @tmpdir
end

Class Method Details

.defaultObject



53
54
55
# File 'lib/image_squeeze.rb', line 53

def self.default
  @processors = self.class.default_processors
end

.default_processorsObject



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/image_squeeze.rb', line 107

def self.default_processors
  processors = []
  ImageSqueeze::Utils.image_utility_available?('identify', 'all image', true)
  if ImageSqueeze::Utils.image_utility_available?('pngcrush', 'pngs and gif')
    processors << PNGCrushProcessor
    processors << GIFToPNGProcessor if ImageSqueeze::Utils.image_utility_available?('convert', 'gif')
  end
  processors << OptiPNGProcessor if ImageSqueeze::Utils.image_utility_available?('optipng', 'png')
  processors << GifsicleProcessor if ImageSqueeze::Utils.image_utility_available?('gifsicle', 'animated gif')
  if ImageSqueeze::Utils.image_utility_available?('jpegtran', 'jpeg')
    processors << JPEGTranProgressiveProcessor
    processors << JPEGTranNonProgressiveProcessor
    processors << PNGToProgressiveJPEGProcessor if ImageSqueeze::Utils.image_utility_available?('convert', 'png')
    processors << PNGToNonProgressiveJPEGProcessor if ImageSqueeze::Utils.image_utility_available?('convert', 'png')
  end
  processors
end

.image_type(filename) ⇒ Object



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/image_squeeze/image_identifier.rb', line 2

def self.image_type(filename)
  return ImageSqueeze::NOT_FOUND unless File.exist?(filename)

  case identified_format(filename)
  when /^GIFGIF/
    ImageSqueeze::ANIMATED_GIF
  when /GIF/
    ImageSqueeze::GIF
  when /JPEG/
    ImageSqueeze::JPEG
  when /PNG/
    ImageSqueeze::PNG
  else
    ImageSqueeze::UNKNOWN
  end
  
end

.loggerObject



99
100
101
# File 'lib/image_squeeze.rb', line 99

def self.logger
  LogFactory.logger
end

.transparent?(filename) ⇒ Boolean

Returns:

  • (Boolean)


20
21
22
# File 'lib/image_squeeze/image_identifier.rb', line 20

def self.transparent?(filename)
  `identify -format "%A %r" #{filename} 2> /dev/null`.split(' ').first == 'True'
end

Instance Method Details

#finalize_result(result) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
# File 'lib/image_squeeze.rb', line 87

def finalize_result(result)
  filename = output_filename = result.filename
  if File.extname(result.filename) != result.output_extension
    output_filename = filename.sub(Regexp.new(Regexp.escape(File.extname(result.filename)) + '$'), result.output_extension)
    FileUtils.mv(result.output_filename, output_filename)
    FileUtils.rm(result.filename)
  else
    FileUtils.mv(result.output_filename, result.filename)
  end
  output_filename
end

#loggerObject



103
104
105
# File 'lib/image_squeeze.rb', line 103

def logger
  self.class.logger
end

#squeeze(filename) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/image_squeeze.rb', line 57

def squeeze(filename)
  image_type = self.class.image_type(filename)
  return if [UNKNOWN, NOT_FOUND].include?(image_type)

  processors = @processors.select{ |processor| processor.handles?(image_type) }
  return if processors.empty?
  
  original_file_size = File.size(filename)
  sorted_results = processors.map do |processor_class|
    output_filename = tmp_filename(filename)
    processor_class.squeeze(filename, output_filename)
    output_file_size = File.size(output_filename)
    result_options = { :filename => filename, :output_filename => output_filename, :bytes_saved => original_file_size - output_file_size, :output_extension => processor_class.output_extension }
    Result.new(result_options)
  end.sort
  
  most_optimized = sorted_results.pop if sorted_results[-1].optimized?
  sorted_results.each do |result|
    FileUtils.rm(result.output_filename)
  end
  most_optimized
end

#squeeze!(filename) ⇒ Object



80
81
82
83
84
85
# File 'lib/image_squeeze.rb', line 80

def squeeze!(filename)
  result = squeeze(filename)
  
  output_filename = filename
  output_filename = finalize_result(result) if result
end