# Nick's web site: imginfo filter. Generate XML representation of image # metadata which can be further processed into a web page. # # Copyright © 2020 Nick Bowler # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . class ImgInfoFilter < Nanoc::Filter identifier :imginfo type :binary => :text require 'exifr/jpeg' require 'fastimage' def do_variant(xml, name, item = @item, rep: :default) file = item.reps[rep].raw_path w, h = FastImage.size(file) sz = File.size(file) xml.variant { xml.name(name) xml.uri(item_uri(item, rep: rep)) xml.width(w) xml.height(h) xml.filesize(human_filesize(sz)) } end def run(filename, params = {}) exif = EXIFR::JPEG.new(filename).to_hash b = Nokogiri::XML::Builder.new do |xml| xml.image { do_variant(xml, "Large", rep: :large) do_variant(xml, "Original") if @item[:description] xml.description(:xmlns => 'http://www.w3.org/1999/xhtml') { xml << @item[:description] } end xml.exif { exif.each do |key, value| # Convert some fields to more useful forms... case key when :f_number, :exposure_bias_value value = sprintf("%.1f", value) when :focal_length value = sprintf("%d\n", value) when :gps_version_id value = value.bytes.join(".") when :exposure_program case value when 1 then value = "Manual" when 2 then value = "Normal program" when 3 then value = "Aperture priority" when 4 then value = "Shutter priority" end when :metering_mode case value when 1 then value = "Average" when 2 then value = "Center weighted average" when 3 then value = "Spot" when 4 then value = "Multi-spot" when 5 then value = "Pattern" when 6 then vlaue = "Partial" end when :flash tmp = if value & 1 == 1 then "Yes" else "No" end case (value >> 3) & 3 when 1, 2 then tmp += ", compulsory" when 3 then tmp += ", auto" end case (value >> 1) & 3 when 2 then tmp += ", return light not detected" when 3 then tmp += ", return light detected" end value = tmp end case value when String value.delete!("\x00") value.strip! when Time # EXIF does not do timezones so don't display one value = value.strftime("%Y-%m-%d %H:%M:%S") end xml.send((key.to_s << "_").to_sym, value.to_s) end } } end b.to_xml end end