65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP缩略图解决方案

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (39投票s)

2002年12月8日

CPOL

6分钟阅读

viewsIcon

458786

downloadIcon

8152

用于生成缩略图和缩略图视图的ASP页面和免费COM对象。

Sample Image - ThumbTools2-1.jpg

重要提示:版本2使用CxImage 6.00编译 - 支持所有文件类型。

引言

几个月前,我写了一篇关于一个C#类生成缩略图以及一个可重用的ASP.NET用户控件显示缩略图视图的文章。一些人要求我将我的解决方案移植到经典ASP。我抽出了一些时间来完成,现在我展示了结果。ASP解决方案在功能上等同于ASP.NET(事实上,许多代码片段已经从C#翻译成VBScript)。只缺少一些高级选项(评论显示和编辑、斜面缩略图、缩略图缓存、缩略图保存),因为它们在经典ASP中难以实现。缩略图视图的解决方案是可重用且易于使用的。您只需进行虚拟包含并在表单中调用服务器函数即可。为了以JPEG格式生成缩略图数据,我创建了一个ATL-COM对象,它是Davide Pizzolato的CxImage的包装器。CxImage是一个C++类,用于加载、保存、显示、转换BMP、JPEG、GIF、PNG、TIFF、MNG、ICO、PCX、TGA、WMF、WBMP、JBG和J2K图像。COM包装器对象也可用于其他任务。例如,您可以创建一个网页,让用户对他们的图像应用图像处理算法。

在本文中,我将介绍如何使用缩略图工具以及代码的重要部分。

如何创建单个缩略图和缩略图视图

缩略图解决方案的ASP部分由文件ThumbGenerate.aspListThumbs.inc组成。下载zip并解压文件后,将包含ThumbAsp文件夹设置为虚拟目录,并将浏览器指向TestListThumbs.asp页面。这是一个测试页面,其一个实例如上图所示。在虚拟路径文本框中输入包含图像的IIS虚拟目录的路径,然后按“提交”按钮。您应该会看到该目录中图像的缩略图。也尝试其他选项,并查看缩略图上的变化。

ThumbGenerate.asp是一个VBScript代码文件,可用于<img>标签中,以动态生成JPEG格式的缩略图。下面显示了ASP文件的典型用法。<a>链接指向一个图像,<img>标签通过其src属性值指定了同一图像的动态生成的缩略图。

<a href='https://codeproject.org.cn/santorini/SANTO007.jpg'>
<img src='https://codeproject.org.cn/ThumbAsp/ThumbGenerate.asp?
    VFilePath=/santorini/SANTO007.jpg&
    Width=200&Height=200&Quality=75'
        border=0 alt='Name: SANTO007.jpg'/></a>

ASP文件的参数以查询字符串的形式给出。它们是以下内容:

  • VFilePath:原始图像的虚拟路径。唯一强制参数。如果指定的文件不存在或不是图像,则会从NoThumb.gif文件生成一个“无缩略图”默认图像。
  • WidthHeight:所需的缩略图大小。如果未给出,则从appSettings读取;如果未在appSettings中指定,则默认为150x150。
  • Quality:JPEG质量参数。范围从1(最低质量)到99(最高质量)。默认为75。
  • AllowStretch:设置为“True”以允许缩略图拉伸以适应上述大小。如果未给出,则默认为False
  • ShellThumbnails:如果未指定或设置为“False”,则使用CxImageATL.dllProgID='CxImageATL.CxImage')中实现的CxImage包装器对象生成缩略图。如果设置为“True”,则使用ThumbExtract.dllProgID='ThumbExtract.FileThumbExtract')中实现的COM对象生成缩略图。后者利用负责在您单击文件或在资源管理器中选择缩略图视图时生成缩略图的shell接口(IExtractImage)。这允许您为各种文件类型(例如,PowerPoint演示文稿)创建缩略图视图,如下图所示。
  • 请参阅我的文章为您的MFC文档类型创建缩略图提取器对象,了解如何通过实现IExtractImage接口来开发一个可以提取任何文件类型的缩略图的COM对象。在同一篇文章中,您可以找到ThumbExtract.dll的代码。

PPT-file thumbnails using the shell-thumbnail extract object

ListThumbs.inc是一个创建缩略图视图的ASP文件。要在ASP页面中使用它,您必须按如下方式包含该文件:

<!-- #include virtual ="/ThumbAsp/ListThumbs.inc" -->

在您想要显示缩略图视图的位置,您需要调用具有以下语法的ListThumbs函数:

ListThumbs(VPath,Columns,Filter,AllowPaging,PageSize,Width,Height,_ 
           Quality, AllowStretch,ShowFilenames,ShellThumbnails)

ListThumbs函数的参数具有以下含义:

  • VPath:您想要显示其内容作为缩略图的虚拟目录。
  • Columns:视图的列数。
  • Filter:用于选择您想要显示缩略图的文件的过滤器(例如,*.jpg;*.gif)。
  • AllowPagingPageSize:设置AllowPaging=True以显示每页包含PageSize个缩略图的页面。要使分页工作,您必须在ASP文档的第一个表单中调用该函数。
  • WidthHeightAllowStretchQualityShellThumbnails:参见上述说明。
  • ShowFilenames:设置ShowFilenames=True以在每个缩略图下方显示相应的文件名。

ListThumbs.incThumbGenerate.asp必须包含在同一个虚拟目录中。当然,您还必须注册COM对象。

源代码解释

如上所述,CxImageATL对象是CxImage图像类的包装器。该类具有加载和保存所有流行图像格式以及各种图像处理和操作函数。对于缩略图生成,使用了Resample函数。我添加了一个名为ImageForASP的新函数,它使用任何支持的图像格式将图像作为Variant字节数组返回。返回的Variant ImageData可以通过调用Response.BinaryWrite ImageData来从ASP页面显示图像。ImageType参数默认为2(JPEG),Quality参数默认为75,并且仅用于JPEG格式。

// method to display image in ASP pages
STDMETHODIMP CCxImage::ImageForASP(long ImageType, long Quality,
                                   VARIANT *ImageData)
{
    SAFEARRAY *psaData; BYTE *pData,*pBuffer; long size;
    SAFEARRAYBOUND rgsabound[1];
 
    m_image.SetJpegQuality((BYTE)Quality);
    CxMemFile memfile; memfile.Open();
    bool bOk = m_image.Encode(&memfile, ImageType);
    if(!bOk) return E_FAIL; // NO-IMAGE
    pBuffer=memfile.GetBuffer();
    size=memfile.Size();
 
    // create safe array and copy image data
    rgsabound[0].lLbound = 0; rgsabound[0].cElements = size;
    psaData = SafeArrayCreate(VT_UI1, 1, rgsabound);
    SafeArrayAccessData(psaData, (void **)&pData);
    memcpy(pData,pBuffer,size);
    SafeArrayUnaccessData(psaData);
    free(pBuffer);
    // put data in variant
    ImageData->vt = (VT_ARRAY | VT_UI1);
    ImageData->parray = psaData;
    return S_OK;
}

ThumbExtract.dll有一个名为ThumbJpgData的等效函数,它以JPEG格式返回缩略图图像数据(再次使用了CxImage文件)。下面是ThumbGenerate.asp文件的代码。唯一棘手的部分是如何保留原始图像的宽高比。另请注意,原始图像的位深度必须增加到24位,因为JPEG不支持索引图像。

<%
Set fso = Server.CreateObject("Scripting.FileSystemObject")
 
Response.ContentType = "image/jpeg"
' ---- parameter parsing ----'
Dim VFilePath,FilePath,Width,Height,Quality,bShellThumbnails,
    bStretch,bCreate
VFilePath = Request("VFilePath")
If Len(VFilePath)=0 Then VFilePath="NoThumb.gif"
FilePath = Server.MapPath(VFilePath)
If Not fso.FileExists(FilePath) Then
  FilePath = Server.MapPath("NoThumb.gif")
End If
If Len(Request("Width"))>0 Then
  Width = Int(Request("Width"))
Else Width = 200
End If
If Len(Request("Height"))>0 Then
  Height = Int(Request("Height"))
Else Height = 200
End If
If Len(Request("Quality"))>0 Then
  Quality = Int(Request("Quality"))
Else Quality = 75
End If
If Len(Request("ShellThumbnails"))>0 Then
  bShellThumbnails = (Request("ShellThumbnails")="True")
Else bShellThumbnails = False
End If
If Len(Request("AllowStretch"))>0 Then
  bStretch = (Request("AllowStretch")="True")
Else bStretch = False
End If
 
Dim BinData
If bShellThumbnails Then
 ' Create COM Shell Thumbnail object
  Set objThumb = Server.CreateObject("ThumbExtract.FileThumbExtract")
  Call objThumb.SetPath(FilePath)
  Call objThumb.SetThumbnailSize(Width,Height)
  Call objThumb.ExtractThumbnail
  BinData = objThumb.ThumbJpgData(Quality)
Else
 ' Create COM CxImage wrapper object
  Set objCxImage = Server.CreateObject("CxImageATL.CxImage")
  Call objCxImage.Load(FilePath,GetFileType(FilePath))
  Call objCxImage.IncreaseBpp(24)
  ' determine thumbnail size and resample original image data
  If Not bStretch Then ' retain aspect ratio
     widthOrig = CDbl(objCxImage.GetWidth())
     heightOrig = CDbl(objCxImage.GetHeight())
     fx = widthOrig/Width
     fy = heightOrig/Height 'subsample factors
     ' must fit in thumbnail size
     If fx>fy Then f=fx Else f=fy  ' Max(fx,fy)
     If f<1 Then f=1
     widthTh = Int(widthOrig/f)
     heightTh = Int(heightOrig/f)
  Else
     widthTh = Width
     heightTh = Height
  End If
  Call objCxImage.Resample(widthTh,heightTh,2)
  BinData = objCxImage.ImageForASP(2,Quality)
End If
 
' output in Response '
Response.BinaryWrite BinData
 
Function GetFileType(sFile)
  dot = InStrRev(sFile, ".")
  filetype=2
  If dot > 0 Then sExt = LCase(Mid(sFile, dot + 1, 3))
  If sExt = "bmp" Then filetype = 0
  If sExt = "gif" Then filetype = 1
  If sExt = "jpg" Then filetype = 2
  If sExt = "png" Then filetype = 3
  If sExt = "ico" Then filetype = 4
  If sExt = "tif" Then filetype = 5
  If sExt = "tga" Then filetype = 6
  If sExt = "pcx" Then filetype = 7
  GetFileType=filetype
End Function

%>  

接下来列出ListThumbs.inc文件的源代码。它本质上是我之前介绍的ASP.NET缩略图用户控件从C#到VBScript的翻译。ASP.NET DataList控件产生的输出可以通过用代码构造HTML表格轻松实现。Columns参数决定了行(<tr>)标签的放置位置。然而,DataList控件的编辑功能很难用ASP代码实现。因此,此版本中我没有实现缩略图评论的编辑和呈现。

<%
 
Function ListThumbs(VPath,Columns,Filter,AllowPaging,PageSize,Width,Height,Quality,
                    AllowStretch,ShowFilenames,ShellThumbnails)
  Set fso = CreateObject("Scripting.FileSystemObject")
  Set ScriptName = Request.ServerVariables("SCRIPT_NAME")
  ScriptPath = Left(ScriptName,InstrRev(ScriptName,"/"))
  If Right(VPath,1)<>"/" Then VPath=VPath & "/"
  path = Server.MapPath(VPath):  If Right(path,1)<>"\" Then path=path & "\"
  ' analyze filter string
  If Len(Filter)=0 Then Filter = "*.gif;*.jpg;*.bmp"
  arSuffixes = Split(Filter,";")
  For i=0 To UBound(arSuffixes)
   pos=Instr(1,arSuffixes(i),".")
   If pos>0 Then arSuffixes(i) = Mid(arSuffixes(i),pos) ' e.g. ".gif"
  Next
  Dim CurPage,TotalPages
  ' -- write client script and hidden field for current page and path
  If AllowPaging Then Call WriteGotoPageScript
  If Len(Request.Form("hdnCurPage"))>0 Then
    CurPage = CInt(Request.Form("hdnCurPage"))
  Else CurPage=1
  End If
  Response.Write "<input type='hidden' name='hdnCurPage' value='" &_
                 CurPage & "' />" & vbCrLf
                ' restart page numbering if different page
  If Request.Form("hdnPrevPath")<> VPath Then CurPage = 1
  Response.Write "<input type='hidden' name='hdnPrevPath' value='" &_
                  VPath & "' />" & vbCrLf
 
  Dim arrFilesAll(),ubn
  If fso.FolderExists(path) Then
    Set oFolder = fso.GetFolder(path)
    For Each oFile in oFolder.Files
      bFileInFilter=False
      For i=0 To UBound(arSuffixes)
        If IsFileOfType(oFile.Name,arSuffixes(i)) Then bFileInFilter=True
      Next
      If bFileInFilter Then
        ReDim Preserve arrFilesAll(ubn)
        arrFilesAll(ubn) = oFile.Name
        ubn=ubn+1
      End If ' if in filter
    Next
   End If
 
  If AllowPaging Then
   TotalPages = CInt(ubn/PageSize)
   If ubn Mod PageSize>0 Then TotalPages = TotalPages + 1
   if TotalPages=0 Then TotalPages=1
    ' make sure current page is in the [1,totalPages] range
   if CurPage>TotalPages  Then
     CurPage=TotalPages
   else
     if CurPage<1 Then CurPage=1
   end if
   ' range of files to read
   StartIndex = (CurPage-1)*PageSize
   EndIndex = CurPage*PageSize
   If ubn < EndIndex Then EndIndex = ubn
  Else
   StartIndex = 0: EndIndex = ubn
  End If
  ' write thumbnail hrefs
  If fso.FolderExists(path) Then
    Response.Write "<TABLE ALIGN='CENTER'>" & vbCrLf
    For index=StartIndex To EndIndex-1
      FileName = arrFilesAll(index)
      ' Response.write path & FileName
      Set oFile=fso.GetFile(path & FileName) : FileSize=oFile.Size
      nCol = nCol+1
      VFilePath = VPath & FileName
      sHREF = "<a href='" & VFilePath & "'>" & _
        "<img src='" & ScriptPath & "ThumbGenerate.asp?VFilePath=" & _
      Server.URLEncode(VFilePath) & "&Width=" &_
                  Width & "&Height=" & Height &_
                  "&Quality=" & Quality & _
                  "&ShellThumbnails=" & ShellThumbnails &_
                  "&AllowStretch=" & AllowStretch & _
                  "' border=0 alt='Name: " & FileName &_
                  "&#10;&#13;Size: " & CInt(FileSize/1024) &_
                  " Kb'/> </a>"
      If nCol = 1 Then Response.Write "<TR>"
       Response.Write "<TD align='Center' " & _
         "style='background-color:White;border-width:1px;" &_
         "border-style:Solid;font-size:8pt;'>" & vbCrLf
       Response.Write sHREF & vbCrLf
       If ShowFilenames Then Response.Write "<br/>" & FileName
       Response.Write "</TD>" & vbCrLf
       If nCol = Columns Then
         Response.Write "</TR>" & vbCrLf
           nCol = 0
       End If
     Next
     Response.Write NumImagesDisplayed(EndIndex-StartIndex,AllowPaging,ubn,_
                                       CurPage,TotalPages)
     If AllowPaging Then
       Response.Write CreateNavBar(VPath,CurPage,TotalPages,Columns)
     End If
     Response.Write "</TABLE>" & vbCrLf
  Else
    Response.Write "Directory Does Not Exist<P>" & vbCrLf
  End If
End Function
 
Function NumImagesDisplayed(NumDisplayed,AllowPaging,TotalFiles,CurPage,TotalPages)
 s = "<tr><td align='Center' colspan='" & Columns &_
     "' style='background-color:#FFFFC0;font-size:8pt;'>"
 s = s & NumDisplayed
 if AllowPaging  Then s = s & " of " & TotalFiles
 ' s = s & " images"
 if AllowPaging Then
   s = s & "  (Page " & CurPage & " of " & TotalPages & ")"
 end if
 s =  s & "</td></tr>"
 NumImagesDisplayed = s
End Function
 
Function CreateNavBar(VPath,CurPage,TotalPages,Columns)
if TotalPages = 1 Then Exit Function
s = "<tr><td align='Center' colspan='" & Columns &_
    "' style='font-size:8pt;'>"
if CurPage>1 Then
  'GoToPage client script updates hidden field with target page
  'and then causes a postback
  s =  s & "<A href=""javascript:GoToPage('" & VPath &_
         "'," & CurPage-1 & _
   ");"">&lt;&lt; Prev</A>  "
End If
for i=1 To TotalPages
  if i=CurPage Then
    s =  s & "<b>" & i & "</b>"
  else
    s =  s & "<A href=""javascript:GoToPage('" & VPath &_
                  "'," & i & ");"">" & _
     i & "</A>"
  end if
  s =  s & " "
  If i Mod 10=0 Then s = s & "<br/>"
Next
If CurPage<TotalPages Then
  s =  s & " <A href=""javascript:GoToPage('" &_
          VPath & "'," & CurPage+1 & _
   ");"">Next &gt;&gt;</A>  "
End If
s =  s & "</td></tr>"
CreateNavBar = s
End Function
 
Function IsFileOfType(afile,infile_type)
  IsFileOfType = (UCase(Right(afile,Len(infile_type)))=UCase(infile_type))
End Function
 
Sub WriteGotoPageScript
 Response.Write "<script language=""javascript"">" & vbCrLf & _
  "//<!--" & vbCrLf & "function GoToPage(vpath,n) { " & vbCrLf & _
  "document.forms(0).hdnCurPage.value=n;" & vbCrLf & _
  "document.forms(0).submit(); " & vbCrLf & _
  "}" & vbCrLf & "//-->" & vbCrLf & "</" & "script>" & vbCrLf
End Sub
 
%>

“注入”到HTML表单中的GoToPage客户端JavaScript函数实现了页面导航。当用户按下任何页面链接时,此函数在客户端执行。它将hdnCurPage隐藏字段的值设置为等于参数n(即页码),然后提交表单。回发后,页码会在页面加载时从隐藏字段中检索。

结论

我还没有在网上找到任何完全免费的ASP缩略图解决方案,所以我希望您会觉得这篇文章和代码有用。如果可以的话,我建议您使用ASP.NET解决方案,因为它更快且有更多选项。似乎.NET的图像处理类具有优化的代码。也许如果您有一台快速PC,您不会注意到差异,但在我的奔腾II上,这很明显。

历史

  • 2002年12月8日:首次发布。
  • 2009年10月31日:文章更新。
© . All rights reserved.