X-Git-Url: https://git.draconx.ca/gitweb/homepage.git/blobdiff_plain/da38a0de6d2814c450ea356412faa03ee54cad68..4f4b3ddd920c95d380a2f25dabd4b68457bb1564:/lib/imginfo.rb diff --git a/lib/imginfo.rb b/lib/imginfo.rb new file mode 100644 index 0000000..13d6b01 --- /dev/null +++ b/lib/imginfo.rb @@ -0,0 +1,111 @@ +# 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