Skip to content

August 20, 2014

How To Optimize PNG Images with TinyPNG

by Dan

TinyPNG is a great service for optimizing and shrinking PNG files. I’ve been using it for several years now. I tried out as many apps, command line tools and services as I could find, and never found anything as easy to use or as high quality.

Most PNG images are created in a way that wastes a lot of space. TinyPNG discovers and removes this wasted space. I’ve found that most of my images are about twice as big as they need to be. And I don’t notice any visual differences after the optimization process. The differences are there, but they are almost impossible to notice unless you know what you’re looking for.

API

When I had only a few images, the website was perfect. Drag-and-drop up to 20 files at once, wait, click to download, done. However, as I added more images, it became a little tricky to keep track of them all.

About a year and a half ago, I started using their new developer API. Whenever I added or changed an image, I would put it in a folder with all my original images. I wrote a script to send all of the files to TinyPNG and then download the optimized versions into a separate folder.

Photoshop Plugin

TinyPNG has a Photoshop plugin too, but I’ve never used it.

Code

This is the script I wrote. It’s a command line tool that takes an input folder and an output folder. The optimized images end up in the output folder.

#!/usr/bin/ruby -w

#
# tinypng.rb — Placed into the public domain by Daniel Reese.
#

require 'rubygems'
require 'json'

# Set API key.
apikey = "your_api_key_goes_here"

# Verify arguments.
ARGV.length == 2 or fail("Usage: ./tinypng.rb <input-folder> <output-folder>")
src = ARGV[0]
dst = ARGV[1]
File.exist?(src) or fail("Input folder does not exist: " + src)
File.exist?(dst) or fail("Output folder does not exist: " + dst)

# Optimize each image in the source folder.
Dir.chdir(src)
Dir.glob('*.png') do |png_file|
    puts "\nOptimizing #{png_file}"

    # Optimize and deflate both images.
    cmd = "curl -u api:#{apikey} --data-binary @#{png_file} 'https://api.tinypng.com/shrink'"
    puts cmd
    r = JSON.parse `#{cmd}`
    if r['error']
        puts "TinyPNG Error: #{r['message']} (#{r['error']})"
        exit(1)
    end
    url = r['output']['url']
    cmd = "curl '#{url}' -o #{dst}/#{png_file}"
    puts cmd
    `#{cmd}`
end
Dir.chdir("..")

puts 'Done'

Recommended

The best part is that TinyPNG is free. If you are using the API and want to optimize more than 500 images a month, or if you are working with files larger than 5MB or so, then you’ll want to subscribe to one of their monthly plans. There are no commitments, so you can switch back to the free plan any time.

Overall, I highly recommend TinyPNG. They are continually tweaking things so that their service is always as good as it can be. The company that runs TinyPNG uses it themselves for their internal development projects. I think that may be why it works so well for developers.

If you want to save disk space and load time, especially for mobile apps, go check it out.

Comments are closed.