Add support for images

This commit is contained in:
2025-12-02 11:43:25 +01:00
parent 15493da657
commit 980192253f
15 changed files with 481 additions and 6 deletions

View File

@@ -0,0 +1,55 @@
# frozen_string_literal: true
require "fastimage"
module Ezdoc
class ImageDimensions
EMUS_PER_INCH = 914_400
DEFAULT_DPI = 96
def self.read(path)
FastImage.size(path) || raise(ArgumentError, "Could not read image dimensions: #{path}")
end
def self.calculate_emus(path, width: nil, height: nil)
native_width, native_height = read(path)
calculate_dimensions_emu(native_width, native_height, width, height)
end
def self.calculate_dimensions_emu(native_width, native_height, width, height)
if width && height
[parse_dimension(width), parse_dimension(height)]
elsif width
w = parse_dimension(width)
ratio = native_height.to_f / native_width
[w, (w * ratio).to_i]
elsif height
h = parse_dimension(height)
ratio = native_width.to_f / native_height
[(h * ratio).to_i, h]
else
pixels_to_emus(native_width, native_height)
end
end
def self.parse_dimension(value)
case value
when Integer
pixels_to_emus(value, 0).first
when /\A(\d+(?:\.\d+)?)\s*in\z/i
(::Regexp.last_match(1).to_f * EMUS_PER_INCH).to_i
when /\A(\d+(?:\.\d+)?)\s*cm\z/i
(::Regexp.last_match(1).to_f * 360_000).to_i
when /\A(\d+(?:\.\d+)?)\s*px\z/i, /\A(\d+)\z/
pixels_to_emus(::Regexp.last_match(1).to_i, 0).first
else
raise ArgumentError, "Invalid dimension format: #{value}. Use '2in', '5cm', '100px', or integer pixels."
end
end
def self.pixels_to_emus(width_px, height_px)
emu_per_pixel = EMUS_PER_INCH / DEFAULT_DPI
[(width_px * emu_per_pixel).to_i, (height_px * emu_per_pixel).to_i]
end
end
end