PyGObject Exif

わざわざ八田川まで通っていた日々は、意味あったジャン。
メジロやキセキレイを見つけた、これらも五条川で見たことない。

メジロってスズメより小さくてカワイイんだよ。
団体行動しかしないからスズメみたいにドコにでもいるわけじゃないんだよ。
しかも全然木から降りてこないし常にアクロバットに動き回っているんだよ。

mejiro

というわけで撮りにいってきた。
キセキレイはまだ一度しか見たことないな、普段ドコにいるんだろう?
ちなみにカワセミは前回とまったく同じ橋の日陰にいた。

ところで。

Fedora の場合 Exif 情報を得るには GExiv2 を使えばいい。
と書いたけど前回の PyObjC のように一覧表示する方法は知らなかった。
ということでチト調べよう。

C
gexiv2/gexiv2-metadata-exif.cpp ? master ? GNOME / gexiv2 ? GitLab

PyGObject
GExiv2.Metadata – Classes – GExiv2 0.10

get_exif_tags で配列を得て get_tag_string すればよさそう。
やってみたら Exif.Panasonic から始まる LUMIX 独自タグがズラリ。
Exif.Panasonic.LensType だけは取得したいな。
最後の LensType だけで見分けしたけど他のメーカーも同じなのかは知らない。

基本的には Exif.Image と Exif.Photo 接頭子のものだけ得られればよさげ。
あと邪魔なので省いたタグについてはソース内の URL で。
ということでこんなコードに。

#!/usr/bin/env python3

import sys, gi
gi.require_version('GExiv2', '0.10')
from gi.repository import GExiv2

def get_exif_dict(filename):
    metadata = GExiv2.Metadata()
    metadata.open_path(filename)
    tags = metadata.get_exif_tags()
    res = {}
    for tag in tags:
        if tag == 'Exif.Photo.MakerNote':
            # https://www.exiv2.org/makernote.html
            continue
        elif tag == 'Exif.Image.PrintImageMatching':
            # https://kotobank.jp/word/PRINT%20Image%20Matching-12107
            continue
        elif tag.startswith('Exif.Image.0x'):
            # https://exiftool.org/TagNames/EXIF.html
            continue
        elif tag.startswith('Exif.Image') or \
                tag.startswith('Exif.Photo') or \
                tag.endswith('LensType'):
            value = metadata.get_tag_string(tag)
            print(f'{tag}: {value}')

d = get_exif_dict(sys.argv[1])

exif

これと PyObjC 版の出力を比較すれば両方で使えるツールを作れそう。
ぶっちゃけデジイチの時点で mac 用しか需要なんて無いんだけど。

PyObjC Exif

よし休日だ。
今日こそ、今度こそは五条川でカワセミを見つけて撮影してやるぞ!
と昼前に遊歩道へ行って十分後。

こんなにあっさり。
わざわざ八田川まで通っていた日々は何だったんだろう。
まあいい、次は狩りの瞬間を撮りたいな。

ところで。

Fedora の場合 Exif 情報を得るには GExiv2 を使えばいい。
macOS の場合はどうすればいいんだろう、ちゃちゃっと検索。

@macosx: NSImage Exif (metadata)

CGImageSource なんてものが SDK にあるみたい。
連想配列を使うのなら PyObjC で書くとスゲェ簡単だぞ。
ImageIO SDK の Objective-c Bridge は以下にあった。

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/Quartz

ということでエラー処理を省いて PyObjC で書き換えてみた。
メソッドの場合は引数の数だけアンダーバーが必要なのを忘れずに。

#!/usr/bin/env python3

from AppKit import *
from Quartz.ImageIO import *
import sys

def get_exif_dict(filename):
    url = NSURL.fileURLWithPath_(filename)
    source = CGImageSourceCreateWithURL(url, None)
    data = CGImageSourceCopyPropertiesAtIndex(source, 0, None)
    return data #['{Exif}']

d = get_exif_dict(sys.argv[1])
print(d)

以上。

macos_exif

dict の中に更に {ExifAux} 等の dict があって細かく情報が得られる。
CFDictionaryRef も Python の dict 同様に添字でアクセスできる。
こんなに楽チンなのに PyObjC って全然流行らないのは何故だろう。

レンズの名前まで記録しているのね、こういう情報が残っていると助かる。
野鳥撮影は楽しいよ、プログラミングの楽しさになんか似ている。

Photo crop

五条川にもカワセミは本当にいるんだね。
某所でセグロさんを撮っていたら目の前を川下に向かって飛ぶエメラルドが!
そして追いかけて、見失う。
ドコで狩してんの?まあ渡り鳥ではないのだから地味に見つけるつもり。

日曜は他にもシジュウカラさんやヤマガラさんも見つける、てか来るんだな。
注意して見ないと全部スズメだと思っちゃうよなって、カワセミさんでさえも。
ポケ GO では画面ばかり見ていたので今迄気が付かなかっただけのようだ。
ピントがイマイチなのしか撮れなかったけど、動き回る小鳥はムズい。

というわけで、gnome-photos の続き。

raw は死ぬほど遅いし RW2 は読み込み不能、管理や観覧には使い物にならない。
でも jpeg なら普通の速度で読み込む、これ切り抜きツールとして使えね?
ようするに Exif データを残した状態で切り抜きしたいのよ。

それと筆者は Fedora から Chrome で iCloud に写真を上げているんだけど。
それを iPhone がダウンロードしちゃう、Mac を立ち上げると Mac にまで。
つまり iCloud への通信が三倍になる、サイズを節約しなきゃマズい。

gnome-photos は基本 XDG_PICTURES_DIR と XDG_DOWNLOAD_DIR 内を探すようだ。
読み込まれたくない写真は XDG_DOCUMENTS_DIR 以下等に退避しておく。
でも筆者の場合写真は全部スレーブ接続した 1TB HDD に入れている。
gnome-photos 起動毎に HDD 内をインポートするかか質問される。
毎回キャンセルするのが面倒なんだけど無効にする設定が無いのが困る。

切り抜きしたい写真を XDG_PICTURES_DIR にコピー。
gnome-photos 起動、その写真がサムネイルに出て来るので選択。
鉛筆のツールボタンを押して「切り抜き」を選択。

crop

三分割の線が出るので三分割法を利用するのが簡単。
完了を押すと切り取りされるが元の写真はそのまま。
gnome-photos という拡張子の XML ファイルに加工内容が記録される。

メニューからエクスポートすると切り取った写真が作成される。
よし Exif 情報が残ったまま切り取り写真のできあがり。

このサイズなら WordPress からでもアップロードできるね。
Mac を使えよという話だが Fedora でやれるのならやりたいじゃん。

GtkDialog

GtkDialog のボタンをメッセージが長くても幅いっぱいに広げる方法が解った。
action_area って実は GtkButtonBox だった。

#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
 
dlg = Gtk.Dialog()
dlg.vbox.pack_start(Gtk.Label(label='a'*50, visible=True), False, False, 30)
dlg.add_button('_OK', Gtk.ResponseType.CLOSE)
dlg.add_button('_Cancel', Gtk.ResponseType.CLOSE)

# Expand
area = dlg.get_action_area()
area.props.layout_style = Gtk.ButtonBoxStyle.EXPAND

dlg.run()
dlg.destroy()

expand_buttons

それだけだったのか。。。。。

ついでに解った。
use-header-bar property を 1 にすれば buttons が headerbar になる。

#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
 
dlg = Gtk.Dialog(use_header_bar=1)
dlg.vbox.pack_start(Gtk.Label(label='Titlebar Buttons', visible=True), False, False, 30)
dlg.add_button('SUZUKI', Gtk.ResponseType.CLOSE)
dlg.add_button('MotorCycle', Gtk.ResponseType.CLOSE)
dlg.add_button('Cool', Gtk.ResponseType.CLOSE)

dlg.run()
dlg.destroy()

titlebar_buttons

そうだったのか。。。。。

それとタイトルバーを消す方法なんだが。
非表示の GtkTitleBar をセットすればとりあえず消すことはできると解った。
でも角が丸くならない、色々試したけど上手くいかない。
で思いついた、GtkMessageDialog のボタンを使わず add_button すればよくね?

#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
 
dlg = Gtk.MessageDialog(text='SUZUKI MotorCycle is Bery Cool!', visible=True)
dlg.add_button('_OK', Gtk.ResponseType.CLOSE)
dlg.add_button('_Yes', Gtk.ResponseType.CLOSE)
dlg.add_button('_Agree', Gtk.ResponseType.CLOSE)

dlg.run()
dlg.destroy()

no_titlebar_dialog

何故今迄気が付かなかったんだ。。。。。

てか、統一感を出そうとするなら GtkMessageDialog 継承が一番じゃん。
そんなこんなで我がアプリは結局コレに書き換え。
prev のファイル名表示を追加しようと思ったけどゴチャゴチャするのでヤメ。
Comipoli 0.4.1 公開、本サイト更新のお知らせは久々だな。

ところで、この件でソースコードを見てやろうって思ったんだが。

gtk/gtkmessagedialog.c at master ? GNOME/gtk ? GitHub

gtk_widget_add_css_class という関数を見つけたんだけど。

GtkWidget: GTK 4 Reference Manual

コレって GTK4 からの関数なんですけど。
え、もしかして次の GNOME から GTK4 なんですか?

LibRaw

2020.08.19 の Fedora アップデート。

libraw

あれ、LibRaw ってもしかしてコレのこと?
LibRaw | raw image decoder

最初から入っていたのか gnome-photos を入れたから入ったのかは知らない。
しかし LUMIX の Raw(RW2) を eog にドロップしてもエラーなんだが。
リンク先には Panasonic 14-bit と書いているけど G99 の Raw は違うということか。

よく解らないけど Nikon D3400 の Raw(NEF) をドロップしてみよう。

nikon_nef

おぉ表示できた、けど 160×120 ピクセルでしか表示できない。
埋め込みされているサムネイル画像を表示しているだけっぽい。
gnome-photos で表示したらどうなんだろう?

sijyuukara

普通に Raw のまま表示できるじゃん。
ちなみに RW2 だと落っこちます、Fedora でこんなの久々に見た。

macOS の Photos.app 同様簡易編集できるようです。
Nikon @ Fedora and macOS | Paepoi Blog

しかし適用が死ぬほど遅い!
全部ソフトウエア処理なんだろうな、macOS はそこが強いよね。

とにかく露出や彩度を上げたり切り抜きしてみたりする。
切り抜きで 1920×1080 とかの数値はアスペクト比の目安でピクセル数ではない。

[完了] ボタンを押すと Raw のデータが上書きされる。
基に戻す場合はメニューのプロパティから可能。
jpeg に現像するにはメニューからエクスポートを選択。

で普通に jpeg 現像ができました。

gnome-photos なら macOS の Photos.app の代わりに、ってのはかなり厳しいけど。
何より画像管理機能がただ単にサムネイル表示しているだけって所がさ。
iOS ですら年別や月別で表示できるのにマジで何も無い、さすがにこれは。
編集は死ぬほど遅いし RW2 では表示すらできないしで実用にはほど遠い。

というか macOS がデジカメに関しては凄過ぎ、比べるほうがおかしい。
せめて管理機能が iOS 並みになれば、ということで今後に期待。