第二章:创建缩略图

缩略图创建步骤

要想用AspJpeg创建一个基本图像缩略图,必须采取以下步骤:

  1. 创建一个AspJpeg对象的实例。
  2. 使用Open方法或者OpenBinary方法分别从磁盘或者内存中打开源图像。
  3. 利用属性Width和属性Height分别设置想要的缩略图的宽度和高度。为了保留宽高比,原来的维度可以通过属性OriginalWidth和属性OriginalHeight来获得。
  4. 通过调用Save方法、Binary方法或SendBinary方法,分别把结果得到的缩略图保存到磁盘、内存或者保存为一个HTTP流。

以下代码示例打开了一个磁盘图像,并创建了一个缩略图,它的宽度被硬编码为一个特定的值(在本示例中是100像素),同时保留原来的宽高比。

<% 
' Create instance of AspJpeg
Set Jpeg = Server.CreateObject("Persits.Jpeg")
' Open source image
Jpeg.Open "c:\path\myimage.jpg"

' New width
L = 100

' Resize, preserve aspect ratio
Jpeg.Width = L
Jpeg.Height = Jpeg.OriginalHeight * L / Jpeg.OriginalWidth

' create thumbnail and save it to disk
Jpeg.Save "c:\path\thumbnail.jpg"

%>

在上述示例中,我们通过原来的高度和缩放因数来计算出新的高度,缩放因子是新的宽度和原来的宽度的比值。

如果我们有必要把该缩略图内切到一个给定的矩形中,比如说,把最长的维度(宽或高)设置为一个特定的值,可以使用以下代码:

..
If jpeg.OriginalWidth > jpeg.OriginalHeight Then
   jpeg.Width = L
   jpeg.Height = jpeg.OriginalHeight * L / jpeg.OriginalWidth
Else
   jpeg.Height = L
   jpeg.Width = jpeg.OriginalWidth * L / jpeg.OriginalHeight
End If
...

从AspJpeg 1.4开始,保留宽高比的任务可以简单地通过属性PreserveAspectRatio来实现。如果该属性设置为True,就会在属性Width和属性Height之间创建一个链接,因此一个维度的改变会自动导致另一个维度成比例的改变。使用属性PreserveAspectRatio,上面的代码示例可以被简化成以下代码:

..
jpeg.PreserveAspectRatio = True
If jpeg.OriginalWidth > jpeg.OriginalHeight Then
   jpeg.Width = L
Else
   jpeg.Height = L
End If
...

直接把缩略图发送到浏览器

当使用在一个IIS/ASP环境中时,AspJpeg可以把结果缩略图直接发送到浏览器,不需要在服务器上创建一个临时文件。这可以通过SendBinary方法来实现。该方法类似于Save,但是它并不是把缩略图保存到磁盘中,而是内在地调用了Asp的Response.BinaryWrite方法,从而把图像发送到客户端浏览器。

SendBinary方法必须从一个独立的脚本文件中被调用,这个文件不能包含任何HTML元素标记。这个脚本必须通过一个元素标记<IMG>的元素属性SRC来引用。

代码示例02_manythumbs.asp包含了一些元素标记<IMG>,引用了脚本02_sendbinary.asp并向它传递文件路径以及尺寸参数,如下所示:

<IMG SRC="02_sendbinary.asp?path=<% = Path %>&width=300">

以下是02_sendbinary.asp脚本的ASP/VB脚本和ASP.NET/C#版本。注意缩略图的宽度是通过查询字符串变量width来传递的,而且高度被设置为指定宽度的比例缩放值。

再一次指出,调用了Jpeg.SendBinary方法的脚本不能包含任何HTML标记,否则它生成的数据流会被破坏掉。

在.NET下面,你一定要使用指令<%@ Page aspCompat="True" %> 使SendBinary方法能正常工作。

VB Script:

<%
Response.Expires = 0
' create instance of AspJpeg
Set Jpeg = Server.CreateObject("Persits.Jpeg")

' Open source file
Jpeg.Open( Request("path") )

' Set new height and width
Jpeg.Width = Request("Width")
Jpeg.Height = Jpeg.OriginalHeight * Jpeg.Width / Jpeg.OriginalWidth

' Perform resizing and 
' send resultant image to client browser
Jpeg.SendBinary

%>

C#:

<%@ Import Namespace="System.Web" %>
<%@ Import Namespace="System.Reflection" %>
<%@ Import Namespace="ASPJPEGLib" %>
<%@ Page aspCompat="True" %>

<script runat="server" LANGUAGE="C#">

void Page_Load(Object Source, EventArgs E)
{
// this script may not contain any HTML tags, not even comments

ASPJPEGLib.IASPJpeg objJpeg;
objJpeg = new ASPJPEGLib.ASPJpeg();

// Open source image
objJpeg.Open( Request["path"] );

// Set new width
objJpeg.Width = int.Parse(Request["width"]);

// Preserve aspect ratio
objJpeg.Height = objJpeg.OriginalHeight * objJpeg.Width / objJpeg.OriginalWidth;

// Send thumbnail data to client browser
objJpeg.SendBinary(Missing.Value);
}

</script>

点击以下链接以运行该代码示例:

http://localhost/aspjpeg/manual_02/02_manythumbs.asp

http://localhost/aspjpeg/manual_02/02_manythumbs.aspx

从内存中打开图像

从v1.2版开始,AspJpeg提供了OpenBinary方法,该方法从一个二进制内存源(比如说一个ADO记录集)中打开一个图像,而不是打开一个磁盘文件。你可以使用该方法,以一个数据库中的大二进制对象为源,创建一个缩略图。你还可以利用它打开用AspUpload上传到内存中的图像(这个话题涵盖在下一章中)。 代码示例02_display.asp02_fromdatabase.asp演示了OpenBinary方法。文件02_display.asp简单引用了另一个ASP脚本,02_fromdatabase.asp,用不同的参数调用了多次。文件02_fromdatabase.asp使用OpenBinary方法,而不是Open方法,并传递一个包含了源图像作为参数的ADO记录集值。

脚本02_fromdatabase.asp/aspx如下所示:

VB Script:

<% ' Using ADO, open database with an image blob
strConnect = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" & Server.MapPath("../db/aspjpeg.mdb")
Set rs = Server.CreateObject("adodb.recordset")
SQL = "select image_blob from images2 where id = " & Request("id")
rs.Open SQL, strConnect, 1, 3

Set Jpeg = Server.CreateObject("Persits.Jpeg")

' Open image directly from recordset
Jpeg.OpenBinary rs("image_blob").Value

' Resize
jpeg.Width = Request("Width")

' Set new height, preserve original aspect ratio
jpeg.Height = jpeg.OriginalHeight * jpeg.Width / jpeg.OriginalWidth

Jpeg.SendBinary

rs.Close
%>

C#:

<%@ Import Namespace="System.Web" %>
<%@ Import Namespace="ASPJPEGLib" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.OleDb" %>
<%@ Import Namespace="System.Reflection" %>
<%@ Page aspCompat="True" %>

<script runat="server" LANGUAGE="C#">

void Page_Load(Object Source, EventArgs E)
{
ASPJPEGLib.IASPJpeg objJpeg;
objJpeg = new ASPJPEGLib.ASPJpeg();

// Connect to database
String strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("../db/aspjpeg.mdb");
OleDbConnection myConnection = new OleDbConnection(strConn);
myConnection.Open();

OleDbCommand myCommand = new OleDbCommand("select image_blob from images2 where id = " + Request["id"], myConnection);
OleDbDataReader myReader = myCommand.ExecuteReader();
myReader.Read();

// Open source image
objJpeg.OpenBinary( myReader["image_blob"] );

// Resize
objJpeg.Width = int.Parse(Request["Width"]);

// Set new height, preserve aspect ratio
objJpeg.Height = objJpeg.OriginalHeight * objJpeg.Width / objJpeg.OriginalWidth;

// Create thumbnail and send it directly to client browser
// aspCompat=True is required.
objJpeg.SendBinary( Missing.Value );

myReader.Close();
myConnection.Close();
}
</script>

点击以下链接以运行该代码示例:

http://localhost/aspjpeg/manual_02/02_display.asp

http://localhost/aspjpeg/manual_02/02_display.aspx

输出到内存

除了Save方法和SendBinary方法,AspJpeg还提供了属性Binary,该属性会把结果缩略图返回为一个二进制字节阵列。该属性允许你把缩略图直接保存到数据库中,不需要在磁盘上创建一个临时的文件:

<%
...
Set rs = Server.CreateObject("adodb.recordset")
rs.Open "images", strConnect, 1, 3
rs.AddNew
rs("image_blob").Value = Jpeg.Binary

rs.Update
...
%>

下一章详细讲解了这个属性。

从URL打开远程图像

要想让AspJpeg打开一个用某个URL定位的远程图像,该图像必须先被下载到运行AspJpeg的服务器。为了实施这个下载,必须使用Microsoft XML DOC的XMLHTTP对象。

XMLHTTP对象允许你指定一个URL以下载该图像,然后实施下载,下载到一个内存阵列中,然后它可以被直接传递给AspJpeg的OpenBinary方法。这使你的应用程序不需要在服务器的硬盘上创建一个临时的文件。

VB Script:

<%
Set objHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP")
objHTTP.Open "GET", "http://www.aspjpeg.com/images/ps_logo.gif"
objHTTP.Send
Set Jpeg = Server.CreateObject("Persits.Jpeg")
Jpeg.OpenBinary(objHTTP.responseBody)
...
%>

在.NET中,这段代码有点复杂,因为没有对象实施一个直接下载到内存中的二进制下载:

C#:

<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Net" %>
<%@ Import Namespace="ASPJPEGLib" %>
<script runat="server" LANGUAGE="C#">

void Page_Load(Object Source, EventArgs E)
{
  String Url = "http://www.aspjpeg.com/images/ps_logo.gif";
  WebRequest request = WebRequest.Create(Url);
  WebResponse response = request.GetResponse();

  Stream responseStream = response.GetResponseStream();

  int nLen = (int)response.ContentLength;
  byte[] ImageBytes = new byte[nLen];

  int n = 0;
  int nBuffer = 4096;
  while( n < nLen )
  {
    int nBytesRead = responseStream.Read(ImageBytes, n, 
      (nLen - n < nBuffer) ? nLen - n : nBuffer);
    n += nBytesRead;
  }

  IASPJpeg objJpeg = new ASPJpeg();
  objJpeg.OpenBinary( ImageBytes );
  ...
}

</script>

如果你喜欢这篇文章,敬请给站长打赏↑

除特别注明外,本站所有文章均为本站站长原译,转载请注明出处。