Skip to content
This repository

ChunkyPNG is a pure Ruby library to read and write PNG images and access textual metadata. It has no dependency on RMagick, or any other library for that matter.

See the API documentation on rdoc.info/gems/chunky_png/frames for more information. Also, take a look at the Changelog to see what's new.

Features

  • Decodes any image that the PNG standard allows. This includes all standard color modes with different bit depths and all transparency, interlacing and filtering options.

  • Encodes images supports all color modes (true color, grayscale and indexed) and transparency for all these color modes. The best color mode will be chosen automatically, based on the image’s colors.

  • R/W access to the image’s pixels.

  • R/W access to all image metadata that is stored in chunks.

  • Alpha composition of different images.

  • Memory efficient (uses a Fixnum, i.e. 4 or 8 bytes of memory per pixel, depending on the machine)

  • Reasonably fast for Ruby standards, by only using integer math and a optimized encoding routine. If the performance is not enough have a look at OilyPNG (see github.com/wvanbergen/oily_png), a mixin module that replaces the slowest routines with a C-based implementation.

  • Interoperability with RMagick if you really need to.

Loading image data

You can load PNG from files, IO streams or binary string:

image = ChunkyPNG::Image.from_file('file.png')
File.open('file.png', 'rb') { |io| image = ChunkyPNG::Image.from_io(io) }
image = ChunkyPNG::Image.from_blob(File.read('file.png'))

Using raw RGB(A) streams

Decoding PNG files is slow. If you can control the input data, consider supplying the pixel data as an RGBA or RGB formatted stream, in which all pixels are encoded from left to right, top to bottom, using 1 byte per channel:

image = ChunkyPNG::Image.from_rgba_stream(File.read('pixeldata.rgba')) # or
image = ChunkyPNG::Image.from_rgb_stream(File.read('pixeldata.rgb'))

Loading these kinds of streams is 1500% faster (!) than loading the same image encoded as PNG.

Manipulating images

ChunkyPNG comes with a small library of image manipulation functions, e.g.:

image = ChunkyPNG::Image.from_file('filename.png')
image[0, 0] = ChunkyPNG::Color.rgba(255, 0,0, 128)
image.line(1, 1, 10, 1, ChunkyPNG::Color.from_hex('#aa007f'))
new_image = image.flip_horizontally.rotate_right
image.compose(ChunkyPNG::Image.new(16, 16, ChunkyPNG::Color.rgba(10, 10, 10, 128)))

See the RDoc documentation for drawing methods at rdoc.info/gems/chunky_png/ChunkyPNG/Canvas/Drawing and composition operations at rdoc.info/gems/chunky_png/ChunkyPNG/Canvas/Operations for more information.

Saving image data

You can encode an image to a file, IO stream or binary string:

image.save('filename.png')
File.open('newfile.png', 'wb' ) { |io| image.write(io) }
binary_string = image.to_blob

Encoding options

ChunkyPNG tries to detect the optimal encoding parameters when saving an image. The detection costs some time, and it may choose a slow encoding method. To override the detection mechanism, and always save as RGB or RGBA image, use the @:fast_rgba@ or @:fast_rgb@ modifier when calling save:

image.save('filename.png', :fast_rgb) # for RGB only images.
png_data = image.to_blob(:fast_rgba) # or for RGBA images.

Note that this may result in bloated files, especially if the image uses little colors. The get the smallest images possible by sacrificing speed, use the following call:

image.save('filename.png', :best_compression)

Instead of these options, you can also use a hash with specific options, e.g.:

image.save('filename.png', :color_mode => ChunkyPNG::COLOR_INDEXED, 
           :compression => Zlib::NO_COMPRESSION, :interlace => true)

See the RDoc documentation for the to_datastream method at rdoc.info/gems/chunky_png/ChunkyPNG/Canvas/PNGEncoding#to_datastream-instance_method to see what options are available.

Development

Contributions are gladly accepted, but keep the following in mind:

  • Fork the project, and commit your changes.

  • Always add specs, so I won't break your newly added functionality.

  • Add yardoc style comments (see yardoc.org) to your code so we always have up-to-date documentation.

  • No hard tabs or trailing whitespace please. This drives me MAD!

  • Send me a pull request.

After you have submitted a patch that convinces me that you understand the internals of the library, I can add you as a collaborator to the project if you wish.

More information

This library is MIT licensed and tested with Ruby 1.8.6, 1.8.7 and Ruby 1.9.2, which is highly recommended because of performance gains. Because it is pure Ruby, it will also work on other Ruby implementations like Rubinius.

I have blogged about the implementation of ChunkyPNG on the Floorplanner techblog (techblog.floorplanner.com/tag/chunky_png/).

Something went wrong with that request. Please try again.