Class: SwarmSDK::Tools::ImageExtractors::PdfImageExtractor
- Inherits:
-
Object
- Object
- SwarmSDK::Tools::ImageExtractors::PdfImageExtractor
- Defined in:
- lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb
Overview
Extracts images from PDF documents Only extracts JPEG images (DCTDecode format) which are LLM API compatible Non-JPEG images (FlateDecode, LZWDecode) are skipped because they would require TIFF format which is not supported by LLM APIs Supported LLM image formats: ['png', 'jpeg', 'gif', 'webp']
Class Method Summary collapse
-
.extract_from_page(page, page_number, temp_dir) ⇒ Array<String>
Extract images from a single PDF page.
-
.extract_images(reader, pdf_path) ⇒ Array<String>
Extract all images from a PDF document.
-
.save_as_tiff(stream, page_number, name, temp_dir) ⇒ String?
Save raw image data as TIFF.
-
.save_gray_tiff(stream, page_number, name, temp_dir) ⇒ String
Save grayscale image as TIFF.
-
.save_image(stream, page_number, name, temp_dir) ⇒ String?
Save a PDF image stream to disk Supports JPEG (DCTDecode) and raw formats.
-
.save_jpeg(stream, page_number, name, temp_dir) ⇒ String
Save JPEG image directly from PDF stream.
-
.save_rgb_tiff(stream, page_number, name, temp_dir) ⇒ String
Save RGB image as TIFF.
Class Method Details
.extract_from_page(page, page_number, temp_dir) ⇒ Array<String>
Extract images from a single PDF page
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb', line 37 def extract_from_page(page, page_number, temp_dir) extracted_files = [] # Get XObjects (external objects) from the page xobjects = page.xobjects return extracted_files if xobjects.empty? xobjects.each do |name, stream| # Only process Image XObjects (not Form XObjects) next unless stream.hash[:Subtype] == :Image file_path = save_image(stream, page_number, name, temp_dir) extracted_files << file_path if file_path end extracted_files rescue StandardError # If extraction fails for this page, continue with others [] end |
.extract_images(reader, pdf_path) ⇒ Array<String>
Extract all images from a PDF document
17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb', line 17 def extract_images(reader, pdf_path) image_paths = [] temp_dir = Dir.mktmpdir("pdf_images_#{File.basename(pdf_path, ".*")}") reader.pages.each_with_index do |page, page_index| page_images = extract_from_page(page, page_index + 1, temp_dir) image_paths.concat(page_images) end image_paths rescue StandardError # If image extraction fails, log it but don't fail the entire PDF read [] end |
.save_as_tiff(stream, page_number, name, temp_dir) ⇒ String?
Save raw image data as TIFF
107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb', line 107 def save_as_tiff(stream, page_number, name, temp_dir) color_space = stream.hash[:ColorSpace] case color_space when :DeviceRGB save_rgb_tiff(stream, page_number, name, temp_dir) when :DeviceGray save_gray_tiff(stream, page_number, name, temp_dir) end # Unsupported color spaces return nil rescue StandardError # If conversion fails, skip this image nil end |
.save_gray_tiff(stream, page_number, name, temp_dir) ⇒ String
Save grayscale image as TIFF
149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb', line 149 def save_gray_tiff(stream, page_number, name, temp_dir) filename = File.join(temp_dir, "page-#{page_number}-#{name}.tif") width = stream.hash[:Width] height = stream.hash[:Height] bpc = stream.hash[:BitsPerComponent] || 8 # Build TIFF header for grayscale tiff = ImageFormats::TiffBuilder.build_gray_header(width, height, bpc) tiff << stream.unfiltered_data File.open(filename, "wb") { |file| file.write(tiff) } filename end |
.save_image(stream, page_number, name, temp_dir) ⇒ String?
Save a PDF image stream to disk Supports JPEG (DCTDecode) and raw formats
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb', line 65 def save_image(stream, page_number, name, temp_dir) filter = stream.hash[:Filter] case filter when :DCTDecode # JPEG images can be saved directly - LLM API compatible save_jpeg(stream, page_number, name, temp_dir) when :FlateDecode, :LZWDecode, nil # Skip non-JPEG images to avoid TIFF format (not supported by LLM APIs) # LLM APIs only support: ['png', 'jpeg', 'gif', 'webp'] # These images would require TIFF conversion which causes API errors nil end # Unsupported formats return nil rescue StandardError # If saving fails, skip this image nil end |
.save_jpeg(stream, page_number, name, temp_dir) ⇒ String
Save JPEG image directly from PDF stream
90 91 92 93 94 95 96 97 98 99 |
# File 'lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb', line 90 def save_jpeg(stream, page_number, name, temp_dir) filename = File.join(temp_dir, "page-#{page_number}-#{name}.jpg") # JPEG images can be written directly - the stream.data contains a complete JPEG file File.open(filename, "wb") do |file| file.write(stream.data) end filename end |
.save_rgb_tiff(stream, page_number, name, temp_dir) ⇒ String
Save RGB image as TIFF
128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb', line 128 def save_rgb_tiff(stream, page_number, name, temp_dir) filename = File.join(temp_dir, "page-#{page_number}-#{name}.tif") width = stream.hash[:Width] height = stream.hash[:Height] bpc = stream.hash[:BitsPerComponent] || 8 # Build TIFF header tiff = ImageFormats::TiffBuilder.build_rgb_header(width, height, bpc) tiff << stream.unfiltered_data # Get decompressed raw pixel data File.open(filename, "wb") { |file| file.write(tiff) } filename end |