Shell 技巧 - 在 Apache 中显示图像目录,第二部分

作者:Dave Taylor

上个月,我们开始编写一个 shell 脚本,将枯燥的 Apache 目录显示转变为更有用且更具视觉吸引力的页面,以帮助您了解您有哪些图像以及它们的外观。

通过使用 file 命令,我展示了如何轻松区分实际是图像的文件和不是图像的文件,这样您就不会陷入尝试这样的尴尬境地

<img src=mypage.html alt=mypage.html />

如果您告诉 Web 浏览器尝试将 HTML 源文件显示为图像,那么结果将不会是您想要的!

for 循环中的所有内容

基本脚本使用 for 循环遍历当前目录中的每个文件,使用常见的 shell 结构

for name in *
do
   commands
done

让我指出,这不会显示以 . 开头的文件,这很好,因为它不会显示 . 和 ..,但如果您想耍花招并拥有像 .secret-pict.png 这样的文件名,这可能会成为问题。但是,话又说回来,如果您试图通过将文件变成点文件来隐藏它们,那么这个脚本也忽略它们也是合理的。

正如我之前展示的那样,如果您确实有一个图像文件,那么在 HTML 中显示它的最佳方法是使用类似于以下内容的代码

<img src="filename" alt="filename" />

更好的解决方案可能是标记 alt 标签中的图像,但让我们直接进入循环并添加此代码。回想一下,我正在使用 file 命令来确定什么是图像,什么不是图像,所以现在我们的核心循环看起来像这样

for name in *
do
  if [ ! -z "$(file $name | grep 'image data')" ]
  then
    echo "<img src=$name><br />$name<br /><br />"
  else
    echo "<a href=$name>$name</a><br /><br />"
  fi
done

这效果很好,对于那些被识别为图像的文件,显示图像(及其名称),并且仅显示指向目录中其他文件的超文本引用,而不会错误地指示它们是图像。

请提供缩略图

如果像我一样,您有很多不同尺寸的图像,那么这种方法的问题很快就会显现出来;结果页面会非常庞大!我真正想要显示的是图像的小缩略图或预览,而不是大图像本身。

幸运的是,如果您要求 Web 浏览器执行此操作,它们在缩放图像方面非常出色。例如,如果您有一个 300x300 的图像,但指定了 50 的高度和宽度,则图像会被缩放并在浏览器中自动显示为 50x50。您可能没有意识到的是,如果您只指定不同的高度或宽度值,浏览器也可以缩放图像。换句话说,这样做效果很好

<img src=100x100.png height=50 />

这真是个好消息,因为虽然您可以在 shell 脚本中动态计算图像的大小,但这相当复杂。因此,如果我们只需指定一个参数应始终为给定的高度,您就可以快速获得准缩略图,尽管有时尺寸会很奇怪。

顺便说一句,问题是如果我们说我们总是希望图像的高度为 50 像素并进行适当的缩放,那么 480 像素宽、50 像素高的图像就会变成一个 480 像素宽的缩略图。理想情况下,我们的缩略图应该固定在一个 50x50 的框中,但让我们从一个基本解决方案开始

for name in *
do
  if [ ! -z "$(file $name | grep 'image data')" ]
  then
    echo "<img src=$name alt=$name height=50 />"
    echo "<br />$name<br /><br />"
  else
    echo "<a href=$name>$name</a><br /><br />"
  fi
done

我还为 img 添加了一个 alt 属性,尽管它在显示效果上并没有什么区别。正如您在图 1 中看到的,整体显示效果非常好。但是,我有一个图像 logo-small.png,它的尺寸是 850x40,因此强制高度为 50 像素实际上会通过放大而不是缩小来增加其宽度!

Work the Shell - Displaying Image Directories in Apache, Part II

图 1. 缩略图显示示例

计算图像大小

如果能够确定图像的大小并进行适当的缩放,那将非常有用。在某些版本的 Linux 中,您可以从 file 命令本身获取图像大小信息

$ file xml.gif walt-disney-world-logo.jpg zeralights-logo.png
xml.gif:  GIF image data, version 89a, 36 x 14,
walt-disney-world-logo.jpg: JPEG image data,
JFIF standard 1.01, resolution (DPI), "AppleMark", 72 x 72
zeralights-logo.png: PNG image data, 225 x 93,
8-bit/color RGB, non-interlaced

这里的问题是 file 命令不知道如何确定 JPEG 文件的大小,因此为图像 walt-disney-world-logo.jpg 报告的 72x72 实际上是图像的分辨率,而不是其大小——这是一个可怕的限制,但我们可以勉强接受。无论如何,您应该使用 PNG 格式,而不是 JPEG,对吧?

基于该输出,这是一个 shell 函数,它返回 GIF 和 PNG 图像的高度和宽度,以及 JPEG 和任何非图像文件的空值

figuresize()
{
   image=$1

   fileout="$(file -b "$1")"

   if [ ! -z "$(echo $fileout|grep "GIF image")" ]
   then
     # GIF image, width x height are params 6-8
     width=$(echo $fileout | cut -f6 -d\  )
     height=$(echo $fileout | cut -f8 -d\  )
   elif [ ! -z "$(echo $fileout|grep "PNG imag")" ]
   then
     # PNG image, width x height are params 4-6
     width=$(echo $fileout | cut -f4 -d\  )
     height=$(echo $fileout | cut -f6 -d\  )
   else
     height=""; width=""
   fi
}

现在可以轻松地将其集成到我们原始的循环中,因此我们也可以在输出中显示图像的大小

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

我已经没有空间来展示如何使用该信息来更改缩略图的缩放方式,因此这将不得不延续到下个月,但我鼓励您稍微尝试一下这段代码,看看您会得到什么样的结果。此外,作为提示,如果您想可靠地获取所有图像类型的大小,那么添加到您的 Linux 机器上最好的工具包莫过于 ImageMagick,您可以在 www.imagemagick.org 找到它。

Dave Taylor 是一位拥有 26 年 UNIX 经验的资深人士,Elm Mail System 的创建者,也是畅销书 Wicked Cool Shell ScriptsTeach Yourself Unix in 24 Hours 以及他的 16 本技术书籍的作者。他的主要网站是 www.intuitive.com,他还通过 AskDaveTaylor.com 提供技术支持。

加载 Disqus 评论