Class: Uniword::Images::ImageManager
- Inherits:
-
Object
- Object
- Uniword::Images::ImageManager
- Defined in:
- lib/uniword/images/image_manager.rb
Overview
Orchestrator for image operations on a DocumentRoot.
Works with the document’s image_parts hash (populated during DOCX loading) and the package ZIP to enumerate, extract, insert, and remove images.
Constant Summary collapse
- EMU_PER_PX =
Pixels per EMU at 96 DPI.
9525- EMU_PER_INCH =
Inches per EMU.
914_400- EMU_PER_CM =
Centimeters per EMU.
360_000
Instance Method Summary collapse
-
#extract(output_dir) ⇒ Integer
Extract all images to a directory on disk.
-
#initialize(document) ⇒ ImageManager
constructor
A new instance of ImageManager.
-
#insert(image_path, **options) ⇒ String
Insert an image into the document.
-
#list ⇒ Array<ImageInfo>
List all images in the document.
-
#remove(image_name) ⇒ Boolean
Remove an image by filename from the document.
Constructor Details
#initialize(document) ⇒ ImageManager
Returns a new instance of ImageManager.
38 39 40 |
# File 'lib/uniword/images/image_manager.rb', line 38 def initialize(document) @document = document end |
Instance Method Details
#extract(output_dir) ⇒ Integer
Extract all images to a directory on disk.
Creates output_dir if it does not exist. Each image is written using the filename from the package entry.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/uniword/images/image_manager.rb', line 76 def extract(output_dir) FileUtils.mkdir_p(output_dir) parts = @document.image_parts return 0 unless parts && !parts.empty? parts.each_value do |entry| data = entry[:data] next unless data filename = File.basename(entry[:target].to_s) File.binwrite(File.join(output_dir, filename), data) end parts.size end |
#insert(image_path, **options) ⇒ String
Insert an image into the document.
Reads the file at image_path, registers it in the document’s image_parts, and appends a new paragraph containing an inline image Drawing at the specified position (or at the end).
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/uniword/images/image_manager.rb', line 106 def insert(image_path, **) unless File.exist?(image_path) raise ArgumentError, "Image file not found: #{image_path}" end width_emu = parse_dimension([:width]) height_emu = parse_dimension([:height]) # Register image part via the existing ImageBuilder infrastructure r_id = Builder::ImageBuilder.register_image(@document, image_path) # Determine pixel dimensions for fallback EMU conversion px_w, px_h = Builder::ImageBuilder.read_dimensions(image_path) width_emu ||= px_w * EMU_PER_PX height_emu ||= px_h * EMU_PER_PX # Build the Drawing element drawing = Builder::ImageBuilder.create_drawing( @document, image_path, width: width_emu, height: height_emu, alt_text: [:description] ) # Wrap in a Run and Paragraph, then insert run = Wordprocessingml::Run.new run.drawings << drawing paragraph = Wordprocessingml::Paragraph.new paragraph.runs << run body = @document.body ||= Wordprocessingml::Body.new body.paragraphs ||= [] position = [:position] if position && position < body.paragraphs.size body.paragraphs.insert(position, paragraph) else body.paragraphs << paragraph end r_id end |
#list ⇒ Array<ImageInfo>
List all images in the document.
Returns one ImageInfo per entry in document.image_parts. When pixel dimensions cannot be determined from the binary data, width and height will be nil.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/uniword/images/image_manager.rb', line 49 def list parts = @document.image_parts return [] unless parts && !parts.empty? parts.map do |_r_id, entry| data = entry[:data] px_w, px_h = detect_pixel_dimensions(data) if data name = File.basename(entry[:target].to_s) ImageInfo.new( name: name, path: "word/#{entry[:target]}", content_type: entry[:content_type].to_s, size: data ? data.bytesize : 0, width: px_w, height: px_h, ) end end |
#remove(image_name) ⇒ Boolean
Remove an image by filename from the document.
Removes the matching entry from image_parts. Does NOT remove Drawing references in the document XML; callers should handle that separately if needed.
159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/uniword/images/image_manager.rb', line 159 def remove(image_name) parts = @document.image_parts return false unless parts && !parts.empty? key = parts.find do |_k, entry| File.basename(entry[:target].to_s) == image_name end&.first return false unless key parts.delete(key) true end |