Shell 技巧 - 在 Apache 中显示图像目录,第三部分
在上个月的专栏中,我们构建了目录显示脚本,使其能够智能地列出您的图像文件(为任何其他文件类型提供链接),并且我们还允许显示缩略图。
后一个技巧是通过让 Web 浏览器来完成的。如果您指定的 height 或 width 与实际图像尺寸不同,Web 浏览器会自动缩放图像以适应指定的尺寸。更棒的是,如果您只指定一个尺寸,它会按比例缩放以适应。
让我再稍微解释一下,因为这对于这个特定的脚本项目至关重要。如果您有一张 250x250 像素的图像,并且您想显示 75x75 的缩略图,那么最佳实践当然是同时指定 height=“75” 和 width=“75”。问题是,如果图像实际上是 250x317,并且您想将其缩小到正好 75 像素宽,它应该有多高呢?
您当然可以进行数学计算,但是让浏览器自动为您完成工作要好得多,如果您仅指定 width=“75” 或使用完整的 HTML 语句,就会发生这种情况
<img src="my250x317.png" width="75" />
这样做会缩放它,最终您会得到一张尺寸正好为 75x95 像素的图像。但是,如果您始终约束一个维度,事情可能会崩溃。如果图像实际上是 250x1100,因为它是一个非常高的图形呢?现在缩略图将破坏整个布局,因为它的缩放版本是 330 像素宽,远远超过了图像的 75x75 目标框!
这就是为什么理想的脚本会找出图形的两个维度中哪个更大,然后将较大的那个约束为我们需要的框的大小,让另一个维度 благодаря Web 浏览器自动按比例缩放。而且,这正是我们将要做的!
重要提示: 我意识到让浏览器缩放图像会带来显著的性能损失——即使您想要的是较小的版本,也必须下载整个全尺寸图像。如果这是一个问题,您可以使用诸如 ImageMagick 之类的工具来缩放图像并创建要显示的缩略图,可能会将它们放入缓存中,并在需要时动态创建新缩略图。但老实说,您难道没有高带宽的互联网连接吗,并且多一两秒的加载时间真的重要吗?
上个月,我们创建了非常有用的脚本函数 figuresize,当给定图形图像时,如果可以计算,它会返回高度和宽度参数。脚本中产生的主循环最终看起来像这样
for name in * do if [ ! -z "$(file -b $name|grep 'image data')" ] then figuresize $name if [ ! -z "$height" ] ; then echo "<img src=$name alt=$name height=50 />" echo "<br />$name ($height x $width)<br />" else echo "<img src=$name alt=$name height=50 />" echo "<br />$name<br />" fi else echo "<a href=$name>$name</a><br /><br />" fi done
如果您仔细阅读代码,它实际上并没有对高度和宽度参数做任何智能的事情,只是在输出中显示它们。相反,让我们将其转换为一个测试,以找出哪个更大。但在我这样做之前,我们需要对循环进行一些基本的改进,以便输出更具吸引力
for name in * do if [ ! -z "$(file -b $name|grep 'image data')" ] then figuresize $name if [ ! -z "$height" ] ; then echo "<a href=$name><img src=$name border=0" echo "alt=$name height=$size " echo "align="absmiddle" />" echo "$name ($height x $width)</a>" else echo "<a href=$name><img src=$name border=0" echo "alt=$name height=$size" echo "align="absmiddle" />" echo "$name</a>" fi else echo "<a href=$name>$name</a><br />" fi echo "<hr />" done
运行此改进后的脚本(其中图像可点击,条目之间有水平线等等)的结果如图 1 所示。
现在,让我们看看如何使脚本更智能
if [ ! -z "$height" ] ; then if [ $height -gt $width ] ; then dimensionlabel="height" else dimensionlabel="width" fi
您能看到我在这里做了什么吗?这使我们能够找出图形的两个维度中哪个更大,然后将 dimensionlabel 设置为该特定维度。这是结果
echo "<img src=$name $dimensionlabel=$size />"
在其中我将 size 设置为所需的缩略图大小——在我们的示例脚本中为 75。
我还将添加一些计数器,以便我们可以在最后总结显示的图像与显示的文件总数。只是因为它,呃,有趣,对吧?
这是循环的最新版本,正如您可能期望的那样,随着它变得越来越复杂,它也变得越来越复杂
for name in * do if [ ! -z "$(file -b $name|grep 'image data')" ] then imgcount=$(( $imgcount + 1 )) figuresize $name if [ ! -z "$height" ] ; then if [ $height -gt $width ] ; then dimensionlabel="height" else dimensionlabel="width" fi echo "<a href=$name><img src=$name border=0" echo "alt=$name $dimensionlabel=$size" echo "align="absmiddle" />" echo "$name ($height x $width)</a>" else echo "<a href=$name><img src=$name border=0" echo "alt=$name height=$size" echo "align="absmiddle" />" echo "$name</a>" fi else echo "<a href=$name>$name</a><br />" fi echo "<hr />" totcount=$(( $totcount + 1 )) done echo "<i>Displayed $imgcount images out of $totcount entries total.</i>"
结果输出(希望更具吸引力)如图 2 所示。
既然我们可以在脚本中规范化这些缩略图(至少对于非 JPEG 图像,由于 file 命令的限制),接下来要研究的是如何在网格或表格中跨多张图像显示结果,而不是像我们现在看到的那样每行一张。这有点复杂,因为它涉及另一个计数器,但在您等待下一期 Linux Journal 的同时,您不妨复习一下基本的 HTML 表格标签,因为那正是我们将要使用的。然后,最后,我们将从 file 切换到 ImageMagick,以便我们可以获取所有图像文件的尺寸,而不仅仅是 GIF 和 PNG 文件。
Dave Taylor 是 UNIX 系统的 26 年资深人士,Elm 邮件系统的创建者,以及最近畅销书 Wicked Cool Shell Scripts 和 Teach Yourself Unix in 24 Hours 的作者,在他的 16 本技术书籍中。他的主要网站是 www.intuitive.com,他还提供技术支持,网址为 AskDaveTaylor.com。