Câu trả lời:
Tôi là người sáng lập Yorba, nhà sản xuất Shotwell. Cảm ơn câu hỏi của bạn.
Shotwell 0.7 ghi siêu dữ liệu (như thẻ và tiêu đề) vào ảnh khi bạn xuất chúng. Siêu dữ liệu được viết ở định dạng EXIF, IPTC và / hoặc XMP (tùy thuộc vào loại nào trong số này có trong ảnh để bắt đầu). Hầu hết các chương trình ảnh khác có thể đọc các định dạng này, vì vậy nếu bạn xuất ảnh từ Shotwell thì các chương trình khác sẽ có thể đọc các thẻ của chúng mà không gặp vấn đề gì.
Shotwell 0.8 sắp tới có thể ghi siêu dữ liệu vào các tệp ảnh khi đang di chuyển - để bật tùy chọn này, chọn tùy chọn " Viết thẻ, tiêu đề và siêu dữ liệu khác vào tệp ảnh " trong hộp thoại tùy chọn . Khi mục này được chọn, Shotwell sẽ cập nhật siêu dữ liệu trong tệp ảnh ngay khi bạn gắn thẻ chúng. Để sử dụng tính năng này, hãy xây dựng trung kế Shotwell từ nguồn (xem http://yorba.org/shotwell/install/#source ) hoặc chỉ chờ Shotwell 0.8 (chúng tôi dự định phát hành vào cuối tháng 12).
Thật không may, Shotwell dường như giữ các thẻ trong cơ sở dữ liệu riêng của mình thay vì nhúng chúng dưới dạng exif, IPTC hoặc XMP trong ảnh. Bạn có thể kiểm tra bằng cách sử dụng exiftool, có thể được cài đặt bằng cách cài đặt gói libimage-exiftool-perl , có sẵn trong kho.
sử dụng lệnh; exiftool testpicture.jpg
để kiểm tra ảnh có tên testpicture.jpg mà trước đây bạn đã gắn thẻ với Shotwell. Bạn sẽ thấy rằng đầu ra exiftool không chứa thẻ Shotwell.
Tiện ích exiftool có thể gắn thẻ ảnh của bạn nhúng các thẻ trong ảnh và điều hay ở đây là hầu hết các trình quản lý ảnh sẽ sử dụng chúng, bao gồm cả Shotwell. Ví dụ:
exiftool -keywords=favourite -keywords=family testpicture.jpg
Thay thế danh sách từ khóa hiện tại bằng hai từ khóa mới (yêu thích và gia đình).
Khi testpicture.jpg được nhập vào Shotwell, ảnh sẽ được gắn thẻ yêu thích và gia đình
Có thể hữu ích khi biết rằng cơ sở dữ liệu Shotwell là cơ sở dữ liệu sqlite nằm trong của bạn; ~/.shotwell/data
thư mục và thường được gọi là photo.db, bạn có thể sao chép nó ở một nơi khác trên máy tính của bạn và truy cập nó bằng sqlite.
Có một vài giao diện GUI cho sqlite, có một cho firefox ở đây hoặc bạn có thể sử dụng sqliteman . Cả hai giao diện này đều có tính năng xuất sang csv; khi bạn xuất các thẻ của mình sang csv (Giá trị phân tách bằng dấu phẩy), bạn có thể kiểm tra xem có phần mềm quản lý ảnh nào khác sẽ nhập và ánh xạ các thẻ vào trường thích hợp trong cơ sở dữ liệu của chúng không. Tôi tin Digikam có thể làm điều này. Digikam cũng có thể nhúng dữ liệu exif vào ảnh.
Hy vọng khi Shotwell đạt được nhiều tính năng hơn, tình huống này sẽ thay đổi.
CẬP NHẬT: Mặc dù đúng là Shotwell 0.7 không lưu trữ các thẻ của nó trong ảnh khi các thẻ này được tạo, các thẻ có thể được nhúng vào ảnh nếu bạn chọn xuất chúng, cảm ơn Adam vì đã làm rõ điều này. Hy vọng việc xuất khẩu này là không mất mát khi xử lý jpeg. Tôi nghi ngờ đó là, nếu người ta chọn kích thước ban đầu cho tùy chọn Thu nhỏ trong hộp thoại xuất.
Mã python nhanh (bẩn?) Để thực hiện việc này mà không cần nâng cấp Shotwell (Tôi nghĩ là từ 0.8.x Shotwell có thể viết ra các thẻ, nhưng bạn không thể nâng cấp lên trên Lucid). Điều này sẽ viết ra xếp hạng sao dưới dạng thẻ (rõ ràng là bình luận, nếu bạn không muốn điều đó).
Yêu cầu exiftool. Nó sẽ sao chép bất kỳ thẻ nào có trong cơ sở dữ liệu shotwell VÀ hình ảnh (tức là những cái mà Shotwell đã nhập khi nhập hình ảnh) vì vậy hãy coi chừng điều đó. Ngoài ra, mất khá nhiều thời gian cho một bộ sưu tập lớn các bức ảnh.
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)
Nếu bạn muốn có một công cụ / trình duyệt GUI thực sự tốt sẽ cho phép bạn gắn thẻ hình ảnh của mình bằng các thẻ Exif (và do đó cũng có sẵn trong Shotwell), tôi khuyên bạn nên sử dụng jBrout .
Tôi đã viết về jBrout trên blog của mình .
Để cài đặt nó, hãy truy cập Synaptic, chọn cài đặt / kho lưu trữ, nhấp vào tab "Phần mềm khác", sau đó nhấn nút "Thêm" và dán vào dòng này:
deb http://jbrout.free.fr/doad/debian nhị phân /
Sau đó tải lại và tìm kiếm jBrout.
Vì ~/.shotwell/data/photo.db
được xác định là photo.db: SQLite 3.x database
bằng lệnh tập tin, tôi đã sử dụng SQLite Database Browser
( sqlitebrowser
) để mở nó.
Hmmm ... bạn có thể đọc nó :-) Nó có tính năng xuất CVS.
Đây không phải là cách tiếp cận GUI bình thường nhưng có một cách.
Tôi đã thử sử dụng tập lệnh của user38122 để phân tích cơ sở dữ liệu shotwell và nó không hoạt động. Rõ ràng lược đồ đã được thay đổi trong các phiên bản gần đây. Thay vào đó tôi đã viết đoạn script sau sử dụng gấu trúc (mà cá nhân tôi thích viết SQL) để thực hiện giao điểm thẻ. Trong ví dụ dưới đây, tôi hiển thị tất cả các hình ảnh có cả thẻ 'mèo' và thẻ 'đang ngủ'.
#!/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'