]> git.draconx.ca Git - homepage.git/blobdiff - lib/imginfo.rb
First stab at images and git-annex.
[homepage.git] / lib / imginfo.rb
diff --git a/lib/imginfo.rb b/lib/imginfo.rb
new file mode 100644 (file)
index 0000000..13d6b01
--- /dev/null
@@ -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 <https://www.gnu.org/licenses/>.
+
+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