{"id":13457003,"url":"https://github.com/toy/image_optim","last_synced_at":"2025-05-12T13:18:53.142Z","repository":{"id":2167066,"uuid":"3113269","full_name":"toy/image_optim","owner":"toy","description":"Optimize images using multiple utilities","archived":false,"fork":false,"pushed_at":"2025-04-29T18:59:06.000Z","size":4122,"stargazers_count":1527,"open_issues_count":38,"forks_count":109,"subscribers_count":35,"default_branch":"main","last_synced_at":"2025-05-12T13:18:33.984Z","etag":null,"topics":["image-optimisation","image-optimization","ruby"],"latest_commit_sha":null,"homepage":"https://github.com/toy/image_optim","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/toy.png","metadata":{"files":{"readme":"README.markdown","changelog":"CHANGELOG.markdown","contributing":"CONTRIBUTING.markdown","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2012-01-05T21:03:14.000Z","updated_at":"2025-05-03T09:37:23.000Z","dependencies_parsed_at":"2024-01-17T08:00:06.166Z","dependency_job_id":"aac4924d-89a7-4d82-aee2-b973212c69ac","html_url":"https://github.com/toy/image_optim","commit_stats":{"total_commits":1124,"total_committers":35,"mean_commits":"32.114285714285714","dds":0.06316725978647686,"last_synced_commit":"c3b543cdc99097575207cb26c42d9d367f4f22f3"},"previous_names":[],"tags_count":68,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toy%2Fimage_optim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toy%2Fimage_optim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toy%2Fimage_optim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toy%2Fimage_optim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/toy","download_url":"https://codeload.github.com/toy/image_optim/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253745196,"owners_count":21957319,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["image-optimisation","image-optimization","ruby"],"created_at":"2024-07-31T08:01:31.657Z","updated_at":"2025-05-12T13:18:53.103Z","avatar_url":"https://github.com/toy.png","language":"Ruby","readme":"[![Gem Version](https://img.shields.io/gem/v/image_optim?logo=rubygems)](https://rubygems.org/gems/image_optim)\n[![Check](https://img.shields.io/github/actions/workflow/status/toy/image_optim/check.yml?label=check\u0026logo=github)](https://github.com/toy/image_optim/actions/workflows/check.yml)\n[![Rubocop](https://img.shields.io/github/actions/workflow/status/toy/image_optim/rubocop.yml?label=rubocop\u0026logo=rubocop)](https://github.com/toy/image_optim/actions/workflows/rubocop.yml)\n[![CodeQL](https://img.shields.io/github/actions/workflow/status/toy/image_optim/codeql.yml?label=codeql\u0026logo=github)](https://github.com/toy/image_optim/actions/workflows/codeql.yml)\n[![Code Climate](https://img.shields.io/codeclimate/maintainability/toy/image_optim?logo=codeclimate)](https://codeclimate.com/github/toy/image_optim)\n[![Code Climate Coverage](https://img.shields.io/codeclimate/coverage/toy/image_optim?logo=codeclimate)](https://codeclimate.com/github/toy/image_optim)\n[![Depfu](https://img.shields.io/depfu/toy/image_optim)](https://depfu.com/github/toy/image_optim)\n[![Inch CI](https://inch-ci.org/github/toy/image_optim.svg?branch=master)](https://inch-ci.org/github/toy/image_optim)\n\n# image_optim\n\nCommand line tool and ruby interface to optimize (lossless compress, optionally lossy) jpeg, png, gif and svg images using external utilities:\n\n* [advpng](http://advancemame.sourceforge.net/doc-advpng.html) from [AdvanceCOMP](http://advancemame.sourceforge.net/comp-readme.html)\n(will use [zopfli](https://code.google.com/p/zopfli/) on default/maximum level 4)\n* [gifsicle](http://www.lcdf.org/gifsicle/)\n* [jhead](http://www.sentex.net/~mwandel/jhead/)\n* [jpegoptim](http://www.kokkonen.net/tjko/projects.html)\n* [jpeg-recompress](https://github.com/danielgtaylor/jpeg-archive#jpeg-recompress)\n* jpegtran from [Independent JPEG Group's JPEG library](http://www.ijg.org/)\n* [optipng](http://optipng.sourceforge.net/)\n* [oxipng](https://github.com/shssoichiro/oxipng)\n* [pngcrush](http://pmt.sourceforge.net/pngcrush/)\n* [pngout](http://www.advsys.net/ken/util/pngout.htm)\n* [pngquant](http://pngquant.org/)\n* [svgo](https://github.com/svg/svgo)\n\nBased on [ImageOptim.app](http://imageoptim.com/).\n\nDocumentation for [latest gem version](http://rubydoc.info/gems/image_optim/frames) and [master branch](http://rubydoc.info/github/toy/image_optim/master/frames).\n\nA test application with latest `image_optim` and `image_optim_pack` is available on render: https://iopack.onrender.com/.\n\n## Gem installation\n\n```sh\ngem install image_optim\n```\n\nYou may also want to install [`image_optim_pack`](https://github.com/toy/image_optim_pack) (see [Binaries pack](#binaries-pack)).\n\n```sh\ngem install image_optim_pack\n```\n\n### Bundler\n\nAdd to your `Gemfile`:\n\n```ruby\ngem 'image_optim'\n```\n\nWith `image_optim_pack`:\n\n```ruby\ngem 'image_optim'\ngem 'image_optim_pack'\n```\n\nWith version:\n\n\u003c!---\u003cupdate-version\u003e--\u003e\n```ruby\ngem 'image_optim', '~\u003e 0.31'\n```\n\u003c!---\u003c/update-version\u003e--\u003e\n\nIf you want to check latest changes:\n\n```ruby\ngem 'image_optim', :git =\u003e 'git://github.com/toy/image_optim.git'\n```\n\n## Docker\n\nThis gem is also be available as [docker image](https://github.com/toy/image_optim_pack/pkgs/container/image_optim) containing most binaries:\n\n```bash\ndocker run --rm ghcr.io/toy/image_optim --version # image_optim version\ndocker run --rm ghcr.io/toy/image_optim --info # image_optim info including bin versions\ndocker run --rm -v \"$PWD\":/here -w /here ghcr.io/toy/image_optim image-in-this-folder.jpg\n```\n\nSee [image_optim_pack repository](https://github.com/toy/image_optim_pack) for [Dockerfile](https://github.com/toy/image_optim_pack/blob/master/Dockerfile) and [instructions](https://github.com/toy/image_optim_pack#docker).\n\n## Binaries location\n\nSimplest way for `image_optim` to locate binaries is to install them in common location present in `PATH` (see [Binaries installation](#binaries-installation)).\n\nIf you cannot install to common location, then install to custom one and add it to `PATH`.\n\nSpecify custom bin location using `XXX_BIN` environment variable (`JPEGOPTIM_BIN`, `OPTIPNG_BIN`, `JPEG_RECOMPRESS_BIN`, …).\n\nBesides permanently setting environment variables in `~/.profile`, `~/.bash_profile`, `~/.bashrc`, `~/.zshrc`, … they can be set:\n\n* before command:\n\n  `PATH=\"/custom/location:$PATH\" image_optim *.jpg`\n\n  for example:\n\n  `PATH=\"/Applications/ImageOptim.app/Contents/MacOS:$PATH\" image_optim *.jpg`\n\n* inside script:\n\n  `ENV['PATH'] = \"/custom/location:#{ENV['PATH']}\"; ImageOptim.optimize_images([…])`\n\n  for example:\n\n  `ENV['PATH'] = \"/Applications/ImageOptim.app/Contents/MacOS:#{ENV['PATH']}\"; ImageOptim.optimize_images([…])`\n\n## Binaries installation\n\n### Binaries pack\n\nEasiest way to get latest versions of most binaries for `image_optim` for Linux and Mac OS X is by installing [`image_optim_pack`](https://github.com/toy/image_optim_pack) gem.\n\nCheck installation instructions in [Gem installation](#gem-installation) section.\n\nPack doesn't include `pngout` and `svgo` binaries, their installation instructions are provided below.\n\n### Linux - Debian/Ubuntu\n\n```bash\nsudo apt-get install -y advancecomp gifsicle jhead jpegoptim libjpeg-progs optipng pngcrush pngquant\n```\n\nIf you get an old version of `pngquant`, please check how to install up-to-date version or compile from source at [http://pngquant.org/](http://pngquant.org/).\n\n### Linux - RHEL/Fedora/Centos\n\n```bash\nsudo yum install -y advancecomp gifsicle jhead libjpeg optipng pngquant\n```\n\nYou may also need to install `libjpeg-turbo-utils` instead of `libjpeg`:\n\n```bash\nsudo yum install -y libjpeg-turbo-utils\n```\n\nYou will also need to install `jpegoptim` and `pngcrush` from source:\n\n#### jpegoptim\n\nReplace `X.Y.Z` with latest version number from http://www.kokkonen.net/tjko/projects.html#jpegoptim.\n\n```bash\nJPEGOPTIM_VERSION=X.Y.Z\ncd /tmp\ncurl -O http://www.kokkonen.net/tjko/src/jpegoptim-$JPEGOPTIM_VERSION.tar.gz\ntar zxf jpegoptim-$JPEGOPTIM_VERSION.tar.gz\ncd jpegoptim-$JPEGOPTIM_VERSION\n./configure \u0026\u0026 make \u0026\u0026 make install\n```\n\n#### pngcrush\n\nReplace `X.Y.Z` with latest version number from http://sourceforge.net/projects/pmt/files/pngcrush/.\n\n```bash\nPNGCRUSH_VERSION=X.Y.Z\ncd /tmp\ncurl -O http://iweb.dl.sourceforge.net/project/pmt/pngcrush/$PNGCRUSH_VERSION/pngcrush-$PNGCRUSH_VERSION.tar.gz\ntar zxf pngcrush-$PNGCRUSH_VERSION.tar.gz\ncd pngcrush-$PNGCRUSH_VERSION\nmake \u0026\u0026 cp -f pngcrush /usr/local/bin\n```\n\n### OS X: Macports\n\n```bash\nsudo port install advancecomp gifsicle jhead jpegoptim jpeg optipng pngcrush pngquant\n```\n\n### OS X: Brew\n\n```bash\nbrew install advancecomp gifsicle jhead jpegoptim jpeg optipng oxipng pngcrush pngquant jonof/kenutils/pngout\n```\n\n### oxipng installation (optional)\n\nUnless it is available in your chosen package manager, can be installed using cargo:\n\n```bash\ncargo install oxipng\n```\n\n### pngout installation (optional)\n\nIf you installed the dependencies via brew, pngout should be installed already. Otherwise, you can install `pngout` by downloading and installing the [binary versions](http://www.jonof.id.au/kenutils).\n\n_Note: pngout is free to use even in commercial soft, but you can not redistribute, repackage or reuse it without consent and agreement of creator. [license](http://advsys.net/ken/utils.htm#pngoutkziplicense)_\n\n### svgo installation (optional)\n\n`svgo` is available from NPM.\n\n```bash\nnpm install -g svgo\n```\n\nIf you prefer to install `svgo` to your project directory, use one of the following commands instead:\n\n```bash\nnpm install svgo\n\nyarn add svgo\n```\n\nWhen installing `svgo` to the project directory, you must add the following to your environment:\n\n```\nSVGO_BIN='node_modules/svgo/bin/svgo'\n```\n\n### jpeg-recompress installation (optional)\n\nDownload and install the `jpeg-recompress` binary from the [JPEG-Archive Releases](https://github.com/danielgtaylor/jpeg-archive/releases) page,\nor follow the instructions to [build from source](https://github.com/danielgtaylor/jpeg-archive#building).\n\n## Usage\n\n### From shell\n\n```sh\nimage_optim *.{jpg,png,gif,svg}\n\nimage_optim -r .\n\nimage_optim -h\n```\n\n### From ruby\n\nInitialize optimizer (or you can call optimization methods directly on `ImageOptim`):\n\n```ruby\nimage_optim = ImageOptim.new\n\nimage_optim = ImageOptim.new(:pngout =\u003e false)\n\nimage_optim = ImageOptim.new(:nice =\u003e 20)\n```\n\nOptimize image getting temp path:\n\n```ruby\nimage_optim.optimize_image('a.png')\n```\n\nOptimize image in place:\n\n```ruby\nimage_optim.optimize_image!('b.jpg')\n```\n\nOptimize image data:\n\n```ruby\nimage_optim.optimize_image_data(data)\n```\n\nMultiple images:\n\n```ruby\nimage_optim.optimize_images(Dir['*.png']) do |unoptimized, optimized|\n  if optimized\n    puts \"#{unoptimized} =\u003e #{optimized}\"\n  end\nend\n\nimage_optim.optimize_images!(Dir['*.*'])\n\nimage_optim.optimize_images_data(datas)\n```\n\n### From rails\n\nRails image assets optimization is extracted into [image\\_optim\\_rails gem](https://github.com/toy/image_optim_rails).\n\n## Configuration\n\nConfiguration in YAML format will be read and prepended to options from two paths:\n\n* `$XDG_CONFIG_HOME/image_optim.yml` (by default `~/.config/image_optim.yml`)\n* `.image_optim.yml` in current working directory\n\nPaths can be changed using `:config_paths` option and `--config-paths` argument.\n\nExample configuration:\n\n```yaml\nnice: 20\npngout: false # disable\noptipng:\n  level: 5\n```\n\n### Temporary directory\n\n`image_optim` uses standard ruby library for creating temporary files. Temporary directory can be changed using one of `TMPDIR`, `TMP` or `TEMP` environment variables.\n\n## Options\n\n* `:nice` — Nice level, priority of all used tools with higher value meaning lower priority, in range `-20..19`, negative values can be set only if run by root user *(defaults to `10`)*\n* `:threads` — Number of threads or disable *(defaults to number of processors)*\n* `:verbose` — Verbose output *(defaults to `false`)*\n* `:pack` — Require image\\_optim\\_pack or disable it, by default image\\_optim\\_pack will be used if available, will turn on `:skip-missing-workers` unless explicitly disabled *(defaults to `nil`)*\n* `:skip_missing_workers` — Skip workers with missing or problematic binaries *(defaults to `false`)*\n* `:allow_lossy` — Allow lossy workers and optimizations *(defaults to `false`)*\n* `:cache_dir` — Configure cache directory\n* `:cache_worker_digests` - Also cache worker digests along with original file digest and worker options: updating workers invalidates cache\n* `:timeout` — Maximum time in seconds to spend on one image, note multithreading and cache *(defaults to unlimited)*\n\nWorker can be disabled by passing `false` instead of options hash or by setting option `:disable` to `true`.\n\n\u003c!---\u003cworker-options\u003e--\u003e\n\u003c!-- markdown for worker options is generated by `script/update_worker_options_in_readme` --\u003e\n\n### advpng:\n* `:level` — Compression level: `0` - don't compress, `1` - fast, `2` - normal, `3` - extra, `4` - extreme *(defaults to `4`)*\n\n### gifsicle:\n* `:interlace` — Interlace: `true` - interlace on, `false` - interlace off, `nil` - as is in original image (defaults to running two instances, one with interlace off and one with on)\n* `:level` — Compression level: `1` - light and fast, `2` - normal, `3` - heavy (slower) *(defaults to `3`)*\n* `:careful` — Avoid bugs with some software *(defaults to `false`)*\n\n### jhead:\nWorker has no options\n\n### jpegoptim:\n* `:allow_lossy` — Allow limiting maximum quality *(defaults to `false`)*\n* `:strip` — List of markers to strip: `:com`, `:exif`, `:iptc`, `:icc`, `:xmp`, `:none` or `:all` *(defaults to `:all`)*\n* `:max_quality` — Maximum image quality factor `0`..`100`, ignored in default/lossless mode *(defaults to `100`)*\n\n### jpegrecompress:\n* `:allow_lossy` — Allow worker, it is always lossy *(defaults to `false`)*\n* `:quality` — JPEG quality preset: `0` - low, `1` - medium, `2` - high, `3` - veryhigh *(defaults to `3`)*\n* `:method` — Comparison Metric: `mpe` - Mean pixel error, `ssim` - Structural similarity, `ms-ssim` - Multi-scale structural similarity (slow!), `smallfry` - Linear-weighted BBCQ-like (may be patented) *(defaults to ssim)*\n\n### jpegtran:\n* `:copy_chunks` — Copy all chunks *(defaults to `false`)*\n* `:progressive` — Create progressive JPEG file *(defaults to `true`)*\n* `:jpegrescan` — Use jpegtran through jpegrescan, ignore progressive option *(defaults to `true`)*\n\n### optipng:\n* `:level` — Optimization level preset: `0` is least, `7` is best *(defaults to `6`)*\n* `:interlace` — Interlace: `true` - interlace on, `false` - interlace off, `nil` - as is in original image *(defaults to `false`)*\n* `:strip` — Remove all auxiliary chunks *(defaults to `true`)*\n\n### oxipng:\n* `:level` — Optimization level preset: `0` is least, `6` is best *(defaults to `3`)*\n* `:interlace` — Interlace: `true` - interlace on, `false` - interlace off, `nil` - as is in original image *(defaults to `false`)*\n* `:strip` — Remove all auxiliary chunks *(defaults to `true`)*\n\n### pngcrush:\n* `:chunks` — List of chunks to remove or `:alla` - all except tRNS/transparency or `:allb` - all except tRNS and gAMA/gamma *(defaults to `:alla`)*\n* `:fix` — Fix otherwise fatal conditions such as bad CRCs *(defaults to `false`)*\n* `:brute` — Brute force try all methods, very time-consuming and generally not worthwhile *(defaults to `false`)*\n* `:blacken` — Blacken fully transparent pixels *(defaults to `true`)*\n\n### pngout:\n* `:copy_chunks` — Copy optional chunks *(defaults to `false`)*\n* `:strategy` — Strategy: `0` - xtreme, `1` - intense, `2` - longest Match, `3` - huffman Only, `4` - uncompressed *(defaults to `0`)*\n\n### pngquant:\n* `:allow_lossy` — Allow quality option *(defaults to `false`)*\n* `:max_colors` — Maximum number of colors to use *(defaults to `256`)*\n* `:quality` — min..max - don't save below min, use less colors below max (both in range `0..100`; in yaml - `!ruby/range 0..100`), ignored in default/lossless mode *(defaults to `100..100`, `0..100` in lossy mode)*\n* `:speed` — speed/quality trade-off: `1` - slow, `3` - default, `11` - fast \u0026 rough *(defaults to `3`)*\n\n### svgo:\n* `:disable_plugins` — List of plugins to disable *(defaults to `[]`)*\n* `:enable_plugins` — List of plugins to enable *(defaults to `[]`)*\n* `:allow_lossy` — Allow precision option *(defaults to `false`)*\n* `:precision` — Number of digits in the fractional part `0`..`20`, ignored in default/lossless mode *(defaults to `3`)*\n\n\u003c!---\u003c/worker-options\u003e--\u003e\n\n## Contributing\n\n[List](https://github.com/toy/image_optim/graphs/contributors) of contributors to `image_optim`.\n\nIf you would like to contribute - that is great and you are very welcome. Please check few notes in file [CONTRIBUTING.markdown](CONTRIBUTING.markdown).\n\n## ChangeLog\n\nIn separate file [CHANGELOG.markdown](CHANGELOG.markdown).\n\n## Copyright\n\nCopyright (c) 2012-2024 Ivan Kuchin. See [LICENSE.txt](LICENSE.txt) for details.\n","funding_links":[],"categories":["Ruby","Imagery","Images","Awesome Ruby CLIs"],"sub_categories":["Converting"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoy%2Fimage_optim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftoy%2Fimage_optim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoy%2Fimage_optim/lists"}