image_size
Measure image size/dimensions using pure Ruby.
Formats: apng, avif, bmp, cur, emf, gif, heic, heif, ico, j2c, jp2, jpeg, jpx, mng, pam, pbm, pcx, pgm, png, ppm, psd, svg, swf, tiff, webp, xbm, xpm.
Installation
gem install image_size
Bundler
Add to your Gemfile:
gem 'image_size', '~> 3.0'
Usage
image_size = ImageSize.path('spec/images/jpeg/436x429.jpeg')
image_size.format #=> :jpeg
image_size.width #=> 436
image_size.height #=> 429
image_size.w #=> 436
image_size.h #=> 429
image_size.size #=> [436, 429]
image_size.size.to_s #=> "436x429"
"#{image_size.size}" #=> "436x429"
image_size.size.width #=> 436
image_size.size.height #=> 429
image_size.size.w #=> 436
image_size.size.h #=> 429
image_size.media_type #=> "image/jpeg"
image_size.media_types #=> ["image/jpeg"]
image_size.byte_size #=> 10938
Or using IO object:
image_size = File.open('spec/images/jpeg/436x429.jpeg', 'rb'){ |fh| ImageSize.new(fh) }
Any object responding to read and eof?:
require 'image_size'
image_size = ImageSize.new(ARGF)
Works with open-uri, see experimental HTTP server interface below:
require 'image_size'
require 'open-uri'
image_size = URI.parse('http://www.rubycgi.org/image/ruby_gtk_book_title.jpg').open('rb') do |fh|
ImageSize.new(fh)
end
image_size = open('http://www.rubycgi.org/image/ruby_gtk_book_title.jpg', 'rb') do |fh|
ImageSize.new(fh)
end
Note that starting with version 2.0.0 the object given to ImageSize will not be rewound before or after use.
So rewind if needed before passing to ImageSize and/or rewind after passing to ImageSize before reading data.
require 'image_size'
File.open('spec/images/jpeg/436x429.jpeg', 'rb') do |fh|
image_size = ImageSize.new(fh)
fh.rewind
data = fh.read
end
File.open('spec/images/jpeg/436x429.jpeg', 'rb') do |fh|
data = fh.read
fh.rewind
image_size = ImageSize.new(fh)
end
Configuration
DPI used for converting svg and emf dimensions can be configured from default 72:
ImageSize.dpi = 150
Chunk size used for reading files, IO and from remote can be configured from default 4096:
ImageSize.chunk_size = 256
Experimental: fetch image meta from HTTP server
If server recognises Range header, only needed chunks will be fetched even for TIFF images, otherwise required amount of data will be fetched, in most cases first few kilobytes (TIFF images is an exception).
require 'image_size/uri'
url = 'http://upload.wikimedia.org/wikipedia/commons/b/b4/Mardin_1350660_1350692_33_images.jpg'
p ImageSize.url(url).size
This interface is as fast as dedicated gem fastimage for images with meta information in the header:
url = 'http://upload.wikimedia.org/wikipedia/commons/b/b4/Mardin_1350660_1350692_33_images.jpg'
puts Benchmark.measure{ p FastImage.size(url) }
[9545, 6623]
0.004176 0.001974 0.006150 ( 0.282889)
puts Benchmark.measure{ p ImageSize.url(url).size }
[9545, 6623]
0.005604 0.001406 0.007010 ( 0.238629)
And considerably faster for images with meta information at the end of file:
url = "https://upload.wikimedia.org/wikipedia/commons/c/c7/Curiosity%27s_Vehicle_System_Test_Bed_%28VSTB%29_Rover_%28PIA15876%29.tif"
puts Benchmark.measure{ p FastImage.size(url) }
[7360, 4912]
0.331284 0.247295 0.578579 ( 6.027051)
puts Benchmark.measure{ p ImageSize.url(url).size }
[7360, 4912]
0.006247 0.001045 0.007292 ( 0.197631)
Configuration
Maximum number of redirects can be configured from default 5:
ImageSize.max_redirects = 10
Or redirects can be disabled:
ImageSize.max_redirects = 0
A url checker can be added to reduce SSRF risk:
ImageSize.uri_checker = lambda do |uri|
raise 'host is not allowed' unless uri.host == 'upload.wikipedia.org'
end
Alternatively private_address_check gem can be of help:
require "private_address_check/tcpsocket_ext"
PrivateAddressCheck.only_public_connections do
ImageSize.url(url).size
end
Licence
This code is free to use under the terms of the Ruby's licence.
Original author: Keisuke Minami keisuke@rccn.com.\ Further development 2010-2026 Ivan Kuchin https://github.com/toy/image_size