我可以导出Shotwell图片数据库保存所有标签吗?

我已经向Shotwell导入了大量图片并花了一些时间来设置标签。 这些标签是否已锁定在Shotwell中,或者我可以将它们导出(再次导入或与其他软件一起使用)?

我是Shotwell制造商Yorba的创始人。 谢谢你的提问。

Shotwell 0.7在导出照片时会将元数据(如标签和标题)写入照片。 元数据以EXIF,IPTC和/或XMP格式编写(取决于照片中的哪些开头)。 大多数其他照片程序可以读取这些格式,因此如果您从Shotwell导出照片,那么其他程序应该能够毫无问题地读取其标签。

即将推出的Shotwell 0.8可以动态地将元数据写入照片文件 – 为此,请在首选项对话框中选择“ 将标签,标题和其他元数据写入照片文件 ”选项 。 选择此选项后,Shotwell将在您标记照片文件后立即更新照片文件中的元数据。 要使用此function,请从源代码构建Shotwell主干(请参阅http://yorba.org/shotwell/install/#source ),或者等待Shotwell 0.8(我们计划在12月晚些时候发布)。

不幸的是,Shotwell确实将标签保存在自己的数据库中,而不是将它们作为exif,IPTC或XMP嵌入到图片中。 您可以使用exiftool进行检查,可以通过安装存储库中提供的libimage-exiftool-perl软件包来安装。

在这里看一些例子

使用命令; exiftool testpicture.jpg查看一张名为testpicture.jpg的照片,该照片之前曾用Shotwell标记过。 您将看到exiftool输出不包含Shotwell标记。

exiftool实用程序可以标记在照片中嵌入标签的图片,这样做的好处是大多数照片管理员都会使用它们,这包括Shotwell。 例如:

 exiftool -keywords=favourite -keywords=family testpicture.jpg 

将现有关键字列表替换为两个新关键字(collections夹和家人)。

当testpicture.jpg被导入Shotwell时,图片将标记为喜欢和家人

知道Shotwell数据库是位于您的数据库中的sqlite数据库可能会有所帮助。 ~/.shotwell/data目录通常称为photo.db,您可以将其复制到计算机上的其他位置并使用sqlite访问它。

sqlite有一些GUI前端,这里有一个firefox或者你可以使用sqliteman 。 这两个前端都导出到csvfunction; 将标签导出到csv(逗号分隔值)时,您可以检查是否有任何其他照片管理软件导入并将标签映射到自己数据库中的相应字段。 我相信Digikam可以做到这一点。 Digikam还可以在照片中嵌入exif数据。

希望Shotwell获得更多function,这种情况会发生变化。

更新:虽然Shotwell 0.7确实不会在创建这些标签时将其标签存储在图片中,但如果您选择导出标签,则可以将标签嵌入图片中,感谢Adam明确表达。 希望这个导出在处理jpeg时是无损的。 我怀疑是,如果在导出对话框中为Scaling选项选择原始大小。

快速(脏?)python代码在没有升级Shotwell的情况下执行此操作(我认为从0.8.x Shotwell可以写出标签,但你无法升级到Lucid上的那个)。 这个东西会把星级评分写成标签(评论说明一点,显然,如果你不想那样)。

需要exiftool。 它将复制shotwell数据库和图像中的任何标签(即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) 

如果你想要一个非常好的GUI工具/浏览器,它可以让你使用Exif标签标记你的图像(因此也可以在Shotwell中使用),我推荐jBrout 。

我在博客上写过关于jBrout的文章 。

要安装它,请转到Synaptic,选择设置/存储库,单击“其他软件”选项卡,然后单击“添加”按钮并粘贴到以下行:

deb http://jbrout.free.fr/download/debian binary /

然后重新加载并搜索jBrout。

由于~/.shotwell/data/photo.db被文件命令识别为photo.db: SQLite 3.x database ,我使用SQLite Database Browsersqlitebrowser )打开它。

嗯…你可以读它:-)它有CVS导出function。

这不是正常的GUI方法,但有一种方法。

我尝试使用user38122的脚本来解析shotwell数据库,但它没有用。 显然,最近版本中的架构已更改。 相反,我编写了以下脚本,使用pandas(我个人更喜欢编写SQL)来做标记交叉。 在下面的示例中,我显示了标签“cat”和标签“sleep”的所有图像。

 #!/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'