我有一个大型 PDF 文档库(论文、讲座、讲义),我希望能够快速浏览。为此,我需要缩略图。
但与此同时,我发现~/.thumbnails
文件夹中堆满了我并不需要的缩略图。如果不删除重要的缩略图,就无法删除缩略图垃圾。如果我要删除它们,我必须进入每个包含重要 PDF 文档的文件夹,让缩略图缓存重新生成。
我希望能够使这个过程自动化。有什么方法可以告诉 nautilus 预先缓存一组给定目录的缩略图?
笔记:我确实找到了一组 bash 脚本似乎对图片和视频有效,但对其他文档无效。也许更有脚本经验的人可以针对 PDF 文档调整这些脚本,或者至少告诉我需要修改哪些地方才能让其适用于 PDF 文档。
编辑:
这个问题的回应非常热烈。首先,我要感谢所有参与解决这个问题的人。这个问题、它的答案以及围绕它的所有讨论都很好地说明了多方的合作努力如何能够带来最佳解决方案。这正是 Linux 和开源如此伟大的原因。
所有提供的答案都值得我最初为这个问题提供的赏金。不过,只有一个赏金可以颁发。我有责任让所有未来的读者选择以最有效方式解决问题的答案。为了确定哪种解决方案,我进行了最后一次测试,比较了这三个脚本的兼容性、速度和输出质量。结果如下:
缩略图 1,作者:rosch:
兼容性:✔ 文件名中有空格;✔ 目录名中有空格;✘ 符合 freedesktop 标准
速度:12.6 秒内处理 95 个 PDF
质量: 库存鹦鹉螺品质
额外福利:1.)自动跳过已有缩略图的文件;2.)无需其他软件包
缩略图 2作者:马丁·奥尔达(Martin Orda):
兼容性:✔ 文件名中有空格;✔ 目录名中有空格;✘ 符合 freedesktop 标准
速度:70.0 秒内处理 95 个 PDF
质量:比库存图片的缩放效果明显更好。
额外福利:1.) 自动跳过已有缩略图的文件 2.) 除 PDF 外还兼容多种图像格式 3.) 独立于平台,不依赖于 GNOME 组件
缩略图 3,作者:詹姆斯·亨斯特里奇:
兼容性:✔ 文件名中有空格;✔ 目录名中有空格;✔ 符合 freedesktop 标准
速度:10.8 秒内处理 95 个 PDF
质量: 库存鹦鹉螺品质
额外福利:1.)自动跳过具有预先存在的缩略图的文件 2.)兼容预装缩略图程序识别的所有文件格式
这三个脚本都很出色。每个脚本都有各自的优点和缺点。Rosch 的解决方案开箱即用,对于安装最少的用户来说可能是正确的选择。
Marcin Kaminski 创造了一个非常多功能脚本它可以处理多种文件格式,并且与 DE 无关。它的缩略图质量很好,但速度却很慢。
最终詹姆斯的解决方案最适合我的用例。它速度快、功能多样,并且提供了跳过已有缩略图文件的选项。
总冠军:詹姆斯·亨斯特里奇
附加信息:所有三个脚本都完全兼容nautilus 脚本.您可以轻松安装它们按照本教程。
编辑2:rosch 更新了评论并改进了脚本。
答案1
Nautilus 的缩略图例程实际上来自libgnome-desktop
库,因此可以在文件管理器之外运行相同的缩略图程序。
API 有点复杂,但以下 Python 脚本应该有帮助:
#!/usr/bin/python
import os
import sys
from gi.repository import Gio, GnomeDesktop
def make_thumbnail(factory, filename):
mtime = os.path.getmtime(filename)
# Use Gio to determine the URI and mime type
f = Gio.file_new_for_path(filename)
uri = f.get_uri()
info = f.query_info(
'standard::content-type', Gio.FileQueryInfoFlags.NONE, None)
mime_type = info.get_content_type()
if factory.lookup(uri, mtime) is not None:
print "FRESH %s" % uri
return False
if not factory.can_thumbnail(uri, mime_type, mtime):
print "UNSUPPORTED %s" % uri
return False
thumbnail = factory.generate_thumbnail(uri, mime_type)
if thumbnail is None:
print "ERROR %s" % uri
return False
print "OK %s" % uri
factory.save_thumbnail(thumbnail, uri, mtime)
return True
def thumbnail_folder(factory, folder):
for dirpath, dirnames, filenames in os.walk(folder):
for filename in filenames:
make_thumbnail(factory, os.path.join(dirpath, filename))
def main(argv):
factory = GnomeDesktop.DesktopThumbnailFactory()
for filename in argv[1:]:
if os.path.isdir(filename):
thumbnail_folder(factory, filename)
else:
make_thumbnail(factory, filename)
if __name__ == '__main__':
sys.exit(main(sys.argv))
将其保存到文件并将其标记为可执行。gir1.2-gnomedesktop-3.0
如果尚未安装该包,您可能还需要安装它。
之后,只需使用要缩略的文件或文件夹作为参数调用该脚本即可。缩略图将保存到~/.thumbnails
Nautilus 等应用程序希望找到它们的位置。
答案2
下面的脚本应该可以完成这项工作。evince-thumbnailer
据我所知,它使用每个 gnome 安装中附带的默认缩略图程序。
另存为 pdfthumbnailer.sh
并使其可执行。
用法:pdfthumbnailer.sh dir1 [dir2, ...]
#!/bin/bash
F1=$HOME/.thumbnails/normal
F2=$HOME/.cache/thumbnails/normal
SAVE_FOLDER=$F1
[ -e $F2 ] && SAVE_FOLDER=$F2
# the thumbnailing function
evincethumb() {
outname=$(echo -n "$(readlink -f "$0")" | \
perl -MURI::file -MDigest::MD5=md5_hex -ne 'print md5_hex(URI::file->new($_));')
# no work if thumbnail already present
[ ! -e $SAVE_FOLDER/${outname}.png ] && {
echo "$0"
#uncomment only one of both thumbnailers
#convert -thumbnail 128x128 "$0"[0] $SAVE_FOLDER/${outname}.png 2>/dev/null
evince-thumbnailer -s 128 "$0" $SAVE_FOLDER/${outname}.png 2>/dev/null
}
}
# make our function visible to the subshell in "find -exec" below
export -f evincethumb
# loop through all given folders
for folder in "$@" ; do
find "$folder" -type f -exec bash -c evincethumb {} \;
done
限制:
- 不会像 James Henstridge 指出的那样将 Thumb::URI 和 Thumb::MTime 属性添加到缩略图。到目前为止,我还没有看到任何证据表明默认设置
evince-thumbnailer
是这样做的。换句话说,只要 nautilus 不重新生成缩略图,该脚本就可以用于这项工作。
笔记:
- 生成新缩略图时打印文件的名称,如果存在则跳过生成
- 速度:使用
evince-thumbnailer
和convert
(来自 imagemagick)测试了 37 个 pdf 文件: 为 3 秒evince-thumbnailer
, 为 14 秒convert
。 - 生成 nautilus 识别的缩略图
- perl URL:file 模块处理的路径名(空格和其他字符被正确地转换为文件 uri)
- 需要
perl
,在默认安装中存在 - 未处理的文件
evince-thumbnailer
将仅输出错误 - 静音2>/dev/null
- 查看 MimeType 行
/usr/share/thumbnailers/evince.thumbnailer
以查看已处理的文件类型的列表 - 更新:从 12.04 开始,缩略图文件夹似乎是
~/.cache/thumbnails
。
使用更强大的路径readlink
。
答案3
有一段时间我分心了,但 rosch 抢先了一步 :) 我不知道 evince-thumbnailer 的存在(我不是 Gnome 用户),但无论如何,既然我已经写过了,就放在这里。它需要安装 imagemagick,如果没有,请检查并安装:
which convert || sudo apt-get install imagemagick
另存为mkthumb.sh
(例如),chmod +x mkthumb.sh
并使用绝对路径作为参数执行它(您可以使用 -s 作为其第一个参数来跳过生成已经存在的缩略图),即:
user@host $ ./mkthumb.sh -s /home/user/Downloads /home/user/blah
Processing directory /home/user/Downloads/pics/
OK /home/user/Downloads/pics/FeO08.jpg
OK /home/user/Downloads/pics/UrOCu.jpg
OK /home/user/Downloads/pics/34ATZ.gif
OK /home/user/Downloads/pics/WBRE3.jpg
OK /home/user/Downloads/pics/LjLdH.jpg
OK /home/user/Downloads/pics/xvvae (1).jpg
SKIP /home/user/Downloads/pics/itcrowd.jpg
OK /home/user/Downloads/pics/76180344.jpg
OK /home/user/Downloads/pics/fgk5N.jpg
....
脚本(我稍微修改了一下以支持大多数图像,如果需要,您可以添加更多扩展):
#!/bin/bash
# USAGE: mkthumb.sh [-s] <abs_path> [abs_path]
# create nautilus thumbnails for images and PDFs in the directories (and their
# sub-directories) given as parameters.
# -s is used to skip generating thumbnails that already exist
skip_existing=0
if [[ "${1}" == "-s" ]]; then
skip_existing=1
shift
fi
mkthumb() {
file="${1}"
dest="${2}"
convert -thumbnail 128x128 "${file}[0]" "${dest}" &>/dev/null
if (( $? == 0 )); then
echo "OK ${file}"
else
echo "FAIL ${file}"
fi
}
OLDIFS="${IFS}"
IFS=$'\n'
for dir in $@; do
realdir=`realpath "${dir}"`
echo "Processing directory ${realdir}"
for file in $(find "${realdir}" -regextype posix-egrep -iregex \
'.*\.(pdf|png|jpg|gif|jpeg)'); do
md5=$(echo -n "${file}" | perl -MURI::file -MDigest::MD5=md5_hex -ne \
'print md5_hex(URI::file->new($_));')
dest="${HOME}/.thumbnails/normal/${md5}.png"
if [[ -f "${dest}" ]]; then
if [[ "${skip_existing}" == "0" ]]; then
mkthumb "${file}" "${dest}"
else
echo "SKIP ${file}"
fi
else
mkthumb "${file}" "${dest}"
fi
done
done
IFS="${OLDIFS}"
它可以毫无问题地处理名称中带有空格的文件。
A bit of testing here:
user@host $ find .thumbnails/
.thumbnails/
.thumbnails/fail
.thumbnails/fail/gnome-thumbnail-factory
.thumbnails/normal
# ok - no thumbnails present.
user@host $ ./mkthumb.sh -s /home/user/Downloads/pdf/test/
Processing directory /home/user/Downloads/pdf/test/
OK /home/user/Downloads/pdf/test/800pdf.pdf
OK /home/user/Downloads/pdf/test/3_TO_pricelist.pdf
OK /home/user/Downloads/pdf/test/111011-speisekarte-mit-desserts.pdf
OK /home/user/Downloads/pdf/test/1186157_r4f3a355eb104a (1).pdf
user@host $ touch tstamp
user@host $ ./mkthumb.sh -s /home/user/Downloads/pdf/test/
Processing directory /home/user/Downloads/pdf/test/
SKIP /home/user/Downloads/pdf/test/800pdf.pdf
SKIP /home/user/Downloads/pdf/test/3_TO_pricelist.pdf
SKIP /home/user/Downloads/pdf/test/111011-speisekarte-mit-desserts.pdf
SKIP /home/user/Downloads/pdf/test/1186157_r4f3a355eb104a (1).pdf
# running nautilus once now to see if it generates new thumbnails
# checking for new thumbnails:
user@host $ find .thumbnails/ -newer tstamp
# None.
答案4
缩略图规范包括共享缩略图存储库,允许将预生成的缩略图与相关文件一起分发,而不是让每个用户生成自己的缩略图。因此,理论上,您可以生成缩略图,然后将它们添加到共享存储库,这样,如果您清除了缩略图目录,或将它们全部移动到其他机器或其他情况下,就无需在将来生成它们。
http://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html#DIRECTORY
当我尝试查找是否有任何应用程序支持共享缩略图存储库时,搜索结果中出现了此 Ask Ubuntu 页面。遗憾的是,似乎没有应用程序支持它们。