├── lib ├── image_optimizer │ ├── version.rb │ ├── png_optimizer.rb │ └── jpeg_optimizer.rb └── image_optimizer.rb ├── spec ├── spec_helper.rb ├── image_optimizer │ ├── version_spec.rb │ ├── png_optimizer_spec.rb │ └── jpeg_optimizer_spec.rb └── image_optimizer_spec.rb ├── Gemfile ├── Rakefile ├── .travis.yml ├── .gitignore ├── image_optimizer.gemspec ├── LICENSE.txt └── README.md /lib/image_optimizer/version.rb: -------------------------------------------------------------------------------- 1 | class ImageOptimizer 2 | VERSION = "1.0.0" 3 | end 4 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH << File.expand_path('../../lib', __FILE__) 2 | require 'image_optimizer' -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in image_optimizer.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require 'rspec/core/rake_task' 3 | 4 | RSpec::Core::RakeTask.new(:spec) 5 | 6 | task :default => :spec -------------------------------------------------------------------------------- /spec/image_optimizer/version_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe ImageOptimizer do 4 | it "should have a VERSION constant" do 5 | ImageOptimizer::VERSION.should_not be_empty 6 | end 7 | end -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - jruby-18mode 4 | - jruby-19mode 5 | - jruby-head 6 | - 1.9.3 7 | - 1.9.2 8 | - rbx-18mode 9 | - rbx-19mode 10 | - ruby-head 11 | - 1.8.7 12 | - ree -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | InstalledFiles 8 | _yardoc 9 | coverage 10 | doc/ 11 | lib/bundler/man 12 | pkg 13 | rdoc 14 | spec/reports 15 | test/tmp 16 | test/version_tmp 17 | tmp 18 | .idea/ -------------------------------------------------------------------------------- /lib/image_optimizer.rb: -------------------------------------------------------------------------------- 1 | require "image_optimizer/version" 2 | require "image_optimizer/jpeg_optimizer" 3 | require "image_optimizer/png_optimizer" 4 | 5 | class ImageOptimizer 6 | attr_reader :path 7 | 8 | def initialize(path) 9 | @path = path 10 | end 11 | 12 | def optimize 13 | JPEGOptimizer.new(path).optimize 14 | PNGOptimizer.new(path).optimize 15 | end 16 | end -------------------------------------------------------------------------------- /spec/image_optimizer_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe ImageOptimizer do 4 | describe "#optimize" do 5 | it 'delegates to jpeg and png optimizers' do 6 | ImageOptimizer::JPEGOptimizer.any_instance.should_receive(:optimize) 7 | ImageOptimizer::PNGOptimizer.any_instance.should_receive(:optimize) 8 | ImageOptimizer.new('/path/to/image.jpg').optimize 9 | end 10 | end 11 | end -------------------------------------------------------------------------------- /image_optimizer.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'image_optimizer/version' 5 | 6 | Gem::Specification.new do |gem| 7 | gem.name = "image_optimizer" 8 | gem.version = ImageOptimizer::VERSION 9 | gem.authors = ["Julian Tescher"] 10 | gem.email = ["jatescher@gmail.com"] 11 | gem.description = %q{A simple image optimizer} 12 | gem.summary = %q{Simply optimize images via jpegoptim or OptiPNG} 13 | gem.homepage = "https://github.com/jtescher/image_optimizer" 14 | 15 | gem.files = `git ls-files`.split($/) 16 | gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } 17 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) 18 | gem.require_paths = ["lib"] 19 | 20 | gem.add_development_dependency "rspec" 21 | gem.add_development_dependency "rake" 22 | end 23 | -------------------------------------------------------------------------------- /spec/image_optimizer/png_optimizer_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe ImageOptimizer::PNGOptimizer do 4 | describe '#optimize' do 5 | let(:file_path) { '/path/to/file.png' } 6 | let(:png_optimizer) { ImageOptimizer::PNGOptimizer.new(file_path) } 7 | 8 | it 'optimizes the png' do 9 | png_optimizer.stub(:png_optimizer_present? => true) 10 | png_optimizer.should_receive(:system).with("optipng -o7 #{png_optimizer.path}") 11 | png_optimizer.optimize 12 | end 13 | 14 | it 'warns the user if the png optimizing utility is not installed' do 15 | png_optimizer.stub(:png_optimizer_present? => false) 16 | png_optimizer.should_receive(:warn).with('Attempting to optimize a png without optipng installed. Skipping...') 17 | png_optimizer.optimize 18 | end 19 | 20 | it 'detects if there is an ENV variable path to optipng' do 21 | png_optimizer.stub(:image_optim_bin_present? => true) 22 | png_optimizer.should_receive(:optimize_png_with_image_optim_bin) 23 | png_optimizer.optimize 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /spec/image_optimizer/jpeg_optimizer_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe ImageOptimizer::JPEGOptimizer do 4 | describe '#optimize' do 5 | let(:file_path) { '/path/to/file.jpg' } 6 | let(:jpeg_optimizer) { ImageOptimizer::JPEGOptimizer.new(file_path) } 7 | 8 | it 'optimizes the jpeg' do 9 | jpeg_optimizer.stub(:jpeg_optimizer_present? => true) 10 | jpeg_optimizer.should_receive(:system).with("jpegoptim -f --strip-all #{jpeg_optimizer.path}") 11 | jpeg_optimizer.optimize 12 | end 13 | 14 | it 'warns the user if the jpeg optimizing utility is not installed' do 15 | jpeg_optimizer.stub(:jpeg_optimizer_present? => false) 16 | jpeg_optimizer.should_receive(:warn).with('Attempting to optimize a jpeg without jpegoptim installed. Skipping...') 17 | jpeg_optimizer.optimize 18 | end 19 | 20 | it 'detects if there is an ENV variable path to jpegoptim' do 21 | jpeg_optimizer.stub(:image_optim_bin_present? => true) 22 | jpeg_optimizer.should_receive(:optimize_jpeg_with_image_optim_bin) 23 | jpeg_optimizer.optimize 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/image_optimizer/png_optimizer.rb: -------------------------------------------------------------------------------- 1 | class ImageOptimizer 2 | class PNGOptimizer 3 | attr_reader :path 4 | 5 | def initialize(path) 6 | @path = path 7 | end 8 | 9 | def optimize 10 | return unless png_format? 11 | 12 | if image_optim_bin_present? 13 | optimize_png_with_image_optim_bin 14 | elsif png_optimizer_present? 15 | optimize_png 16 | else 17 | warn 'Attempting to optimize a png without optipng installed. Skipping...' 18 | end 19 | end 20 | 21 | private 22 | 23 | def png_format? 24 | ['png', 'gif'].include? extension(path) 25 | end 26 | 27 | def extension(path) 28 | path.split(".").last.downcase 29 | end 30 | 31 | def optimize_png 32 | system "optipng -o7 #{path}" 33 | end 34 | 35 | def png_optimizer_present? 36 | `which optipng` && $?.success? 37 | end 38 | 39 | def image_optim_bin_present? 40 | ENV['OPTIPNG_BIN'] != nil 41 | end 42 | 43 | def optimize_png_with_image_optim_bin 44 | system "#{ENV['OPTIPNG_BIN']} -o7 #{path}" 45 | end 46 | 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Julian Tescher 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /lib/image_optimizer/jpeg_optimizer.rb: -------------------------------------------------------------------------------- 1 | class ImageOptimizer 2 | class JPEGOptimizer 3 | attr_reader :path 4 | 5 | def initialize(path) 6 | @path = path 7 | end 8 | 9 | def optimize 10 | return unless jpeg_format? 11 | 12 | if image_optim_bin_present? 13 | optimize_jpeg_with_image_optim_bin 14 | elsif jpeg_optimizer_present? 15 | optimize_jpeg 16 | else 17 | warn 'Attempting to optimize a jpeg without jpegoptim installed. Skipping...' 18 | end 19 | end 20 | 21 | private 22 | 23 | def jpeg_format? 24 | ['jpeg', 'jpg'].include? extension(path) 25 | end 26 | 27 | def extension(path) 28 | path.split(".").last.downcase 29 | end 30 | 31 | def optimize_jpeg 32 | system "jpegoptim -f --strip-all #{path}" 33 | end 34 | 35 | def jpeg_optimizer_present? 36 | `which jpegoptim` && $?.success? 37 | end 38 | 39 | def image_optim_bin_present? 40 | ENV['JPEGOPTIM_BIN'] != nil 41 | end 42 | 43 | def optimize_jpeg_with_image_optim_bin 44 | system "#{ENV['JPEGOPTIM_BIN']} -f --strip-all #{path}" 45 | end 46 | 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ImageOptimizer 2 | 3 | This gem allows you to simply optimize images via jpegoptim or OptiPNG. 4 | 5 | Tested against ruby 1.8.7, 1.9.2, 1.9.3, ruby-head, jruby-18mode, jruby-19mode, jruby-head, rbx-18mode, rbx-19mode, and 6 | ree 7 | 8 | [![Build Status](https://secure.travis-ci.org/jtescher/image_optimizer.png)] 9 | (http://travis-ci.org/jtescher/image_optimizer) 10 | [![Dependency Status](https://gemnasium.com/jtescher/image_optimizer.png)](https://gemnasium.com/jtescher/image_optimizer) 11 | [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/jtescher/image_optimizer) 12 | 13 | ## Installation 14 | 15 | ##### This gem uses the following utilities for optimizing images: 16 | 17 | 1. jpegoptim, which can be installed from [freecode.com](http://freecode.com/projects/jpegoptim) 18 | 19 | 2. OptiPNG, which can be installed from [sourceforge.net](http://optipng.sourceforge.net/) 20 | 21 | Or install the utilities via homebrew: 22 | 23 | ```bash 24 | $ brew install optipng jpegoptim 25 | ``` 26 | 27 | Then add this line to your application's Gemfile: 28 | 29 | gem 'image_optimizer' 30 | 31 | And then execute: 32 | 33 | ```bash 34 | $ bundle 35 | ``` 36 | 37 | Or install it yourself as: 38 | ```bash 39 | $ gem install image_optimizer 40 | ``` 41 | 42 | ## Usage 43 | 44 | #### Optimize PNG or GIF formats: 45 | 46 | OptiPNG is a PNG optimizer that recompresses image files to a smaller size without losing any information and 47 | performs PNG integrity checks and corrections. 48 | 49 | ```ruby 50 | ImageOptimizer.new('path/to/file.png').optimize 51 | ``` 52 | 53 | #### Optimize JPEG formats: 54 | 55 | jpegoptim provides lossless optimization for JPEG files based on optimizing the Huffman tables. 56 | 57 | ```ruby 58 | ImageOptimizer.new('path/to/file.jpg').optimize 59 | ``` 60 | 61 | ## Contributing 62 | 63 | 1. Fork it 64 | 2. Create your feature branch (`git checkout -b my-new-feature`) 65 | 3. Commit your changes (`git commit -am 'Add some feature'`) 66 | 4. Push to the branch (`git push origin my-new-feature`) 67 | 5. Create new Pull Request 68 | --------------------------------------------------------------------------------