답변:
저는 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
기존 키워드 목록을 두 개의 새로운 키워드 (즐겨 찾기 및 제품군)로 바꿉니다.
testpicture.jpg를 Shotwell로 가져 오면 즐겨 찾기 및 가족 태그가 붙습니다.
Shotwell 데이터베이스가 사용자의 sqlite 데이터베이스라는 것을 아는 것이 도움이 될 수 있습니다. ~/.shotwell/data
디렉토리 (일반적으로 photo.db)를 사용하여 컴퓨터의 다른 위치에 복사하여 sqlite로 액세스 할 수 있습니다.
sqlite를위한 GUI 프론트 엔드가 몇 개 있거나 firefox를 위한 GUI 프론트 엔드가 있거나 sqliteman 을 사용할 수 있습니다 . 이 프런트 엔드는 모두 CSV 기능으로 내보내졌습니다. 태그를 csv (쉼표로 구분 된 값)로 내보낼 때 다른 사진 관리 소프트웨어가 태그를 가져 와서 자체 데이터베이스의 해당 필드에 매핑하는지 확인할 수 있습니다. Digikam이 이것을 할 수 있다고 생각합니다. Digikam은 사진 자체에 exif 데이터를 내장 할 수도 있습니다.
Shotwell이 더 많은 기능을 얻게되면이 상황이 바뀔 것입니다.
업데이트 : Shotwell 0.7은 태그를 만들 때 그림에 태그를 저장하지 않지만 태그를 내 보내면 태그를 그림에 포함 할 수 있습니다. jpeg를 다룰 때이 수출이 무손실이기를 바랍니다. 내보내기 대화 상자에서 크기 조정 옵션으로 원래 크기를 선택하면 그 크기가 의심됩니다.
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)
Exif 태그를 사용하여 이미지에 태그를 지정하여 Shotwell에서도 사용할 수있는 정말 좋은 GUI 도구 / 브라우저를 원한다면 jBrout을 권장 합니다 .
나는 한 내 블로그에 jBrout에 대해 설명 .
설치하려면 시냅틱으로 이동하여 설정 / 저장소를 선택하고 "기타 소프트웨어"탭을 클릭 한 다음 "추가"버튼을 누르고 다음 줄에 붙여 넣으십시오.
deb http://jbrout.free.fr/download/debian binary /
그런 다음 jBrout을 다시로드하고 검색하십시오.
shotwell 데이터베이스를 구문 분석하기 위해 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'