投稿者「sasakima-nao」のアーカイブ

Photo management

昨日五条川で見つけた以下が何の鳥なのか解らない。

検索しまくる、やっと解ったぞ。

BIRD FAN (日本野鳥の会) | ゴイサギ

ゴイサギの幼鳥ってまったく別物ジャン、こんなの解るかい!
せっかく綺麗な羽根模様なのに大人になったらアオサギモドキとは。
野鳥の知識ばかりが増えていく今日この頃。

それにしても、野鳥写真が増えまくって Fedora での管理に困っている。
今迄は Nautilus と eog で充分だったけどそろそろ限界を感じてきた。
gnome-photos の進化を待っていられなさそう。

てなわけで、数年ぶりに Shotwell を入れてみる。

あぁなつかしのツリービューとメニューバーが、まあそれはよくて。
サムネイルから選択はシングルクリックじゃないのか、うーん。

日付け選択はサイドバーをクリックもなんかコレじゃない。
そもそもそういう管理なら Nautilus でもいいんだよ、って感じ。
iPhone と macOS の写真アプリに慣れ過ぎた、一画面でやってほしい。

LUMIX の RW2 Raw は読み込みできるみたい。
切り替えは「現像」メニューでできるけどもっと直感的にならないの?
切り抜きとか加工もできる、Exif を残してエクスポートも可能。
Flickr 等との連携も可能、iCloud はそりゃ無理か。

gnome-photos より多機能で速い、けどいかんせん使い勝手が古臭い。
Apple の写真アプリがどんだけよくできているか思い知るだけだった。

もう写真は mac で管理したほうがいいかなと。
そもそも iCloud を利用しているのだしね。
Lightroom も使ってみたい、Fedora を使いたかったので諦めていただけだ。
でも正直観覧なら iPhone が最高、タップだけで使え持ち運べるって素晴らしい。
ただ筆者は最近 SE2 に機種変したので画面がちっちゃい、もう少し大き。。。。。

iPad という手があるじゃない!

RAW現像も写真取り込みにも新型iPad Proが快適。iOS版Lightroom CCで写真編集する時代に – ICS MEDIA

Raw も取り込みできるのか、何も問題無さそう。
ついに筆者も iPad を買う理由ができた、新型 Air が来月出たら買う。
いやメインマシンを Fedora から変える気は無いですよ、今の所は。

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 なんですか?