回答:
ShotwellのメーカーであるYorbaの創設者です。ご質問ありがとうございます。
Shotwell 0.7は、エクスポート時にメタデータ(タグやタイトルなど)を写真に書き込みます。メタデータは、EXIF、IPTC、XMP形式のいずれか、または両方で書き込まれます(最初に写真に含まれていたものに応じて)。他のほとんどの写真プログラムはこれらの形式を読み取ることができるため、Shotwellから写真をエクスポートする場合、他のプログラムは問題なくタグを読み取ることができます。
今後のShotwell 0.8は、その場で写真ファイルにメタデータを書き込むことができます。これを有効にするには、設定ダイアログで「タグ、タイトル、その他のメタデータを写真ファイルに書き込む」オプションを選択します。これが選択されると、Shotwellはタグを付けるとすぐに写真ファイルのメタデータを更新します。この機能を使用するには、ソースからShotwellトランクをビルドするか(http://yorba.org/shotwell/install/#sourceを参照)、またはShotwell 0.8(12月後半にリリースする予定です)を待つだけです。
残念ながら、Shotwellはタグをexif、IPTCまたはXMPとして写真に埋め込むのではなく、独自のデータベースに保持しているようです。リポジトリで利用可能なlibimage-exiftool-perlパッケージをインストールすることでインストールできるexiftoolを使用して確認できます。
コマンドを使用します。exiftool testpicture.jpg
以前にShotwellでタグ付けしたtestpicture.jpgという写真を確認します。exiftoolの出力にはShotwellタグが含まれていないことがわかります。
exiftoolユーティリティは、写真にタグを埋め込んだ写真にタグを付けることができます。これに関する良い点は、ほとんどの写真管理者がそれらを使用することです。これにはShotwellが含まれます。例えば:
exiftool -keywords=favourite -keywords=family testpicture.jpg
既存のキーワードリストを2つの新しいキーワード(お気に入りとファミリー)に置き換えます。
testpicture.jpgがShotwellにインポートされると、写真にお気に入りと家族のタグが付けられます
Shotwellデータベースがsqliteデータベースであることを知っておくと役立つ場合があります。~/.shotwell/data
通常はphoto.dbと呼ばれるディレクトリで、コンピューター上のどこかにコピーしてsqliteでアクセスできます。
sqliteにはGUIフロントエンドがいくつかありますが、ここにはfirefox用のものがあります。または、sqlitemanを使用できます。これらのフロントエンドには両方ともcsv機能へのエクスポートがあります。タグをcsv(カンマ区切り値)にエクスポートすると、他の写真管理ソフトウェアがタグをインポートし、独自のデータベースの適切なフィールドにマップするかどうかを確認できます。Digikamはこれができると信じています。Digikamは、写真自体にexifデータを埋め込むこともできます。
Shotwellがより多くの機能を獲得するにつれて、この状況が変わることを願っています。
更新:Shotwell 0.7はこれらのタグが作成されるときにタグを画像に保存しないのは事実ですが、タグをエクスポートすることを選択した場合、タグを画像に埋め込むことができます。うまくいけば、このエクスポートは、jpegを処理するときにロスレスになります。エクスポートダイアログのスケーリングオプションに元のサイズを選択した場合、そうだと思います。
Shotwellをアップグレードせずにこれを行うクイック(ダーティー?)Pythonコード(0.8.xの時点でShotwellはタグを書き出すことができますが、Lucidではアップグレードできません)。このことは、星の評価をタグとして書き出します(それを望まないのであれば、明らかに、少しだけコメントを付けてください)。
exiftoolが必要です。ショットウェルデータベースと画像(つまり、画像をインポートしたときにShotwellがインポートしたタグ)の両方にあるタグが複製されるため、注意が必要です。また、写真の大きなコレクションにはかなり時間がかかります。
import os
conn = sqlite3.connect("/home/ username /.shotwell/data/photo.db")
def get_tags():
return [ x[0] for x in conn.execute("SELECT name FROM TagTable").fetchall()]
def tag_query(tag):
return conn.execute("SELECT photo_id_list FROM TagTable WHERE name=?", (tag,)).fetchone()[0].split(",")
def get_tagged_photos(tag):
for id in tag_query(tag):
result = conn.execute("select filename from PhotoTable where id=?", (id,) ).fetchone()
if result:
yield result[0]
def get_photos_by_rating(rating):
return [photo[0] for photo in conn.execute("select filename from PhotoTable where rating=?",(rating,)).fetchall()]
def get_tagging_commands():
commands = []
for rating in range(1,5):
for photo in get_photos_by_rating(rating):
commands.append("exiftool -overwrite_original_in_place -preserve -keywords+=rating%d \"%s\""% (rating,photo))
for tag in [tag for tag in get_tags() if tag != "keep"]:
for photo in get_tagged_photos(tag):
commands.append("exiftool -overwrite_original_in_place -preserve -keywords+=%s \"%s\"" % (tag,photo))
return commands
commands = get_tagging_commands()
for command in commands:
print command
os.system(command)
Exifタグを使用して画像にタグを付けることができる(したがってShotwellでも使用できる)本当に優れたGUIツール/ブラウザーが必要な場合は、jBroutをお勧めします。
しました 私のブログにjBroutについて書か。
それをインストールするには、Synapticに行き、設定/リポジトリを選択し、「その他のソフトウェア」タブをクリックしてから、「追加」ボタンを押してこの行に貼り付けます:
deb http://jbrout.free.fr/download/debian binary /
次に、リロードしてjBroutを検索します。
ショットウェルデータベースを解析するためにuser38122のスクリプトを使用しようとしましたが、機能しませんでした。どうやら最近のバージョンでスキーマが変更されたようです。代わりに、パンダ(私は個人的にSQLを書くことを好みます)を使用してタグの交差を行う次のスクリプトを作成しました。以下の例では、タグ「cat」とタグ「sleeping」の両方を持つすべての画像を示しています。
#!/usr/bin/python
# An example of how to query the shotwell database with pandas
import sqlite3, pandas, os, time, datetime
con = sqlite3.connect('/home/dov/.local/share/shotwell/data/photo.db')
photo_df = pandas.read_sql("SELECT * from PhotoTable", con)
for c in ['exposure_time','timestamp','time_created']:
photo_df[c] = photo_df[c].map(datetime.datetime.fromtimestamp)
tag_df = pandas.read_sql('SELECT * from TagTable', con)
def get_image_ids(tag):
"""The image ids are stored morphed in the database as %016x"""
global tag_df
return set([int(s.replace('thumb',''),16)
for s in tag_df[tag_df.name==tag].photo_id_list.iloc[0].split(',')
if len(s)])
def get_photos(ids):
"""Get the photos for a list of ids"""
global photo_df
return photo_df[photo_df.id.isin(ids)].sort(['exposure_time'])
def view_pix(rows):
cmd = ('eog ' + ' '.join(['"%s"'%row.filename
for idx,row in rows.iterrows()]))
# print cmd
os.system(cmd)
print 'querying...'
# An example of how to create an intersection of two tags
ids1 = get_image_ids('cat')
ids2 = get_image_ids('sleeping')
rows = get_photos(ids1.intersection(ids2))
# An example of how to filter the rows by timestamp
time_low,time_high = datetime.datetime(2006,8,1),datetime.datetime(2009,1,1)
rows = rows[(rows.exposure_time > time_low)
& (rows.exposure_time < time_high)]
print '\n'.join([str(ts) for ts in rows['exposure_time']])
view_pix(rows)
print 'done'