philiprehberger-image_size

Tests Gem Version Last updated

Image dimension detection from file headers without full decode

Requirements

  • Ruby >= 3.1

Installation

Add to your Gemfile:

gem "philiprehberger-image_size"

Or install directly:

gem install philiprehberger-image_size

Usage

require "philiprehberger/image_size"

info = Philiprehberger::ImageSize.of("photo.png")
info.width   # => 1920
info.height  # => 1080
info.format  # => :png

Dimensions Only

width, height = Philiprehberger::ImageSize.dimensions("banner.jpg")

Format Detection

format = Philiprehberger::ImageSize.format("image.webp")
# => :webp

IO Objects

File.open("photo.gif", "rb") do |f|
  info = Philiprehberger::ImageSize.of(f)
  puts info.to_s  # => "GIF 320x240"
end

Animation Detection

info = Philiprehberger::ImageSize.of("animation.gif")
info.animated?  # => true

Alpha Channel Detection

info = Philiprehberger::ImageSize.of("transparent.png")
info.alpha?  # => true

EXIF Orientation

info = Philiprehberger::ImageSize.of("rotated.jpg")
info.orientation  # => 6
# Width and height reflect actual display dimensions (swapped for 90/270 rotation)

ImageInfo Value Object

info = Philiprehberger::ImageSize.of("photo.bmp")
info.to_a  # => [640, 480]
info.to_h  # => { width: 640, height: 480, format: :bmp, animated: false, alpha: false, orientation: nil }

Megapixels

info = Philiprehberger::ImageSize.of("photo.png")
info.megapixels  # => 2.1

DPI Extraction

info = Philiprehberger::ImageSize.of("print-ready.jpg")
info.dpi  # => { x: 300.0, y: 300.0 } or nil if not available

Supported sources: JPEG (JFIF APP0), PNG (pHYs chunk), TIFF (resolution tags), BMP (pixels per meter).

Color Depth

info = Philiprehberger::ImageSize.of("photo.png")
info.color_depth  # => 24 (bits per pixel) or nil if not detectable

Supported formats: PNG (bit depth * channels), BMP (from header), JPEG (precision * components from SOF marker).

Interlace Detection

info = Philiprehberger::ImageSize.of("progressive.jpg")
info.interlaced?  # => true (progressive JPEG)

info = Philiprehberger::ImageSize.of("interlaced.png")
info.interlaced?  # => true (Adam7 interlacing)

Computed Properties

info = Philiprehberger::ImageSize.of("photo.png")
info.aspect_ratio  # => 1.78
info.landscape?    # => true
info.portrait?     # => false
info.square?       # => false
info.area          # => 2073600
info.megapixels    # => 2.1
info.rotated?      # => false

Fit Within a Bounding Box

info = Philiprehberger::ImageSize.of("photo.png") # 1920x1080
info.fit_within(400, 400)  # => [400, 225]   # scaled down, aspect preserved
info.fit_within(3000, 3000) # => [1920, 1080] # no upscale

API

Philiprehberger::ImageSize

Method Description
.of(path_or_io) Returns ImageInfo with width, height, format, and metadata
.dimensions(path_or_io) Returns [width, height] array
.format(path_or_io) Returns format symbol (:png, :jpeg, :gif, :bmp, :webp, :tiff, :ico, :cur, :svg, :avif)

Philiprehberger::ImageSize::ImageInfo

Method Description
#width Image width in pixels (display dimensions for rotated JPEG)
#height Image height in pixels (display dimensions for rotated JPEG)
#format Format symbol
#animated? Whether the image is animated (GIF, WebP, APNG)
#alpha? Whether the image has an alpha channel
#interlaced? Whether the image uses interlaced (PNG Adam7) or progressive (JPEG) encoding
#orientation EXIF orientation (1-8), nil if not applicable
#aspect_ratio Width divided by height as Float
#landscape? Whether width > height
#portrait? Whether height > width
#square? Whether width == height
#area Total pixel count (width * height)
#megapixels Area in megapixels, rounded to 1 decimal
#dpi DPI as { x: Float, y: Float } hash, or nil
#color_depth Bits per pixel (PNG, BMP, JPEG), or nil
#rotated? Whether EXIF orientation indicates 90/270 rotation
#fit_within(max_w, max_h) Returns [w, h] scaled to fit inside a bounding box (preserves aspect ratio, never upscales)
#to_a Returns [width, height]
#to_h Returns hash with all attributes
#to_s Returns "FORMAT WxH" string

Development

bundle install
bundle exec rspec
bundle exec rubocop

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT