Module: OllamaChat::Utils::PNGMetadataExtractor
- Extended by:
- UTF8Converter
- Includes:
- UTF8Converter
- Defined in:
- lib/ollama_chat/utils/png_metadata_extractor.rb
Overview
Extracts embedded metadata from PNG image files, such as character profiles, ComfyUI workflows, and prompts stored in 'tEXt' chunks.
Class Method Summary collapse
-
.decode_character(text) ⇒ String?
Decodes a Base64 encoded character profile and validates it as JSON.
-
.extract_all(io) ⇒ Hash?
Extracts all 'tEXt' chunk metadata from the provided IO object.
-
.extract_character(io) ⇒ String?
Convenience method to extract a character profile from a PNG.
-
.parse_a1111_parameters(text) ⇒ Hash?
Parses Automatic1111 / Stable Diffusion WebUI parameters metadata.
Methods included from UTF8Converter
Class Method Details
.decode_character(text) ⇒ String?
Decodes a Base64 encoded character profile and validates it as JSON.
64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/ollama_chat/utils/png_metadata_extractor.rb', line 64 def decode_character(text) return nil unless text begin decoded = Base64.decode64(text) decoded = convert_to_utf8(decoded) JSON.parse(decoded) # Validation check decoded rescue JSON::ParserError, ArgumentError nil end end |
.extract_all(io) ⇒ Hash?
Extracts all 'tEXt' chunk metadata from the provided IO object.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/ollama_chat/utils/png_metadata_extractor.rb', line 16 def extract_all(io) data = if io.respond_to?(:binmode) io.binmode io.read elsif io.respond_to?(:binread) io.binread else return nil end # PNG Signature is 8 bytes: \x89PNG\r\n\x1a\n pos = 8 = {} while pos < data.length # 1. Read Length (4 bytes, Big Endian) length = data[pos, 4]&.unpack1('L>') break unless length pos += 4 # 2. Read Chunk Type (4 bytes) type = data[pos, 4] pos += 4 # 3. Read Chunk Data chunk_data = data[pos, length] pos += length # 4. Skip CRC (4 bytes) pos += 4 if type == 'tEXt' # tEXt chunks are formatted as: Keyword + NULL Byte + Text keyword, text = chunk_data.split("\x00", 2) [keyword] = text if keyword end end .empty? ? nil : ensure io.ask_and_send(:rewind) end |
.extract_character(io) ⇒ String?
Convenience method to extract a character profile from a PNG. Maintained for backward compatibility with existing call sites.
107 108 109 110 |
# File 'lib/ollama_chat/utils/png_metadata_extractor.rb', line 107 def extract_character(io) = extract_all(io) or return decode_character(['chara']) end |
.parse_a1111_parameters(text) ⇒ Hash?
Parses Automatic1111 / Stable Diffusion WebUI parameters metadata.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/ollama_chat/utils/png_metadata_extractor.rb', line 81 def parse_a1111_parameters(text) text or return lines = text.split("\n") result = { prompt: lines[0], negative_prompt: nil, settings: {} } lines[1..].each do |line| if line.start_with?('Negative prompt: ') result[:negative_prompt] = line.sub('Negative prompt: ', '') else # Parse comma-separated key-value pairs (e.g., "Steps: 20, Sampler: Euler") line.split(', ').each do |pair| key, value = pair.split(': ', 2) result[:settings][key.downcase.to_sym] = value if key && value end end end result end |