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

简单的图像调整大小库

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.68/5 (15投票s)

2008年1月18日

CPOL

5分钟阅读

viewsIcon

114308

downloadIcon

3518

一个简单的库,用于管理和缩放上传的图片。

引言

我似乎经常需要处理很多与图片相关的事情,特别是动态缩放图片的问题——所以我决定编写一个库,让这个过程尽可能简单。

背景

这个库的目标是易于使用,并且足够灵活,无论你如何存储图片(文件系统、数据库、亚马逊网络服务等),都可以使用它。至于哪种存储图片的方式“最好”的讨论,我将留给其他人。然而,无论你选择哪种方式,仍然有一些共同的事情需要考虑:缩放图片并保持纵横比、文件名唯一性等。

使用代码

我通常会尝试 **不** 在创建这种简单的库时添加额外的对象——但在这种情况下,我认为它实际上可能会有帮助。要缩放图片,有时需要很多信息:图像流、内容类型、期望的宽度或高度等。因此,与其创建带有大量参数的方法,这个库将使用 ImageInfo 对象,该对象为我们保存了大部分信息。我还将一些方法拆分到两个“管理器”类中:WebManagerFileManager。如果你在代码隐藏页面上使用这个库,那么“WebManager”对象可能是最好的选择——否则,你将使用“FileManager”类。

最棒的是,你可以覆盖或继承几乎任何东西,所以你可以根据自己的具体情况进行修改。

附带的演示项目包含了这里描述的所有示例,以及一个包含该库的独立项目。

示例:保存上传的图片及其缩放版本

在第一个示例中,我们假设刚刚发布了一个 ASPX 页面,并使用 FileUpload 控件选择了要上传的图片。这段代码放在 ButtonSubmit_Click 方法中。

//use WebManager to get the file, and save it
IImageInfo img = WebManager.GetImageInfo(fileUploader);
img.Path = "uploadedImages";
img.Save();
    
//now create resized versions, and save them
IImageInfo imgLarge = img.ResizeMe(null, 300);    //constrain to 300 pixels wide
imgLarge.Save("uploadedImages/large");        //save file in a folder named "large"
    
IImageInfo imgMedium = img.ResizeMe(185, null);    //constrain to 185 pixels high
imgMedium.Save("uploadedImages/medium");

IImageInfo imgSmall = img.ResizeMe(null, 100);    //constrain to 100 pixels wide
imgSmall.Save("uploadedImages/small");

IImageInfo imgTiny = img.ResizeMe(50, null);    //constrain to 50 pixels high
imgTiny.Save("uploadedImages/tiny");

让我们逐行解释上面的示例。第一行调用 WebManager 类上的静态 GetImageInfo 方法。此方法接收 FileUpload,填充一个使用 IImageInfo 接口的对象,其中包含上传图片的原始信息,并返回该对象。

IImageInfo img = WebManager.GetImageInfo(fileUploader);

下一行将 Path 设置为目录“uploadedImages”。这是我们希望将原始上传文件保存到的目录。**请注意,您必须调整此目录的权限,允许 .NET 进程写入。在我这里,我为三个用户授予了“修改”权限:IIS_WPG、ASPNET 和 IIS_IUSRS。

img.Path = "uploadedImages";

下一行简单地调用 ImageInfo 对象上可用的 Save 方法。由于我们没有传递任何参数,此方法将使用其现有的文件名保存上传的图片。

img.Save();

下一行使用 ImageInfo 类上可用的 ResizeMe 方法来缩放它包含的图片,然后返回一个包含缩放后图片的新 ImageInfo 对象。ImageInfo 对象包含与原始图片相同的所有信息(路径、文件名等),但 PhotoStreamWidthHeight 被设置为缩放后的图片尺寸。ResizeMe 方法接受两个可空整数:maxHeightmaxWidth。在这种情况下,我们只关心宽度为 300 像素——所以我们可以将 maxHeight 设置为 null(或 0)。同时设置 maxHeightmaxWidth 参数将缩放图片,使其不会超过 maxHeightmaxWidth。它 **不会** 将图片缩放到指定的 maxHeightmaxWidth 的确切尺寸——它仍然会保持正确的纵横比。在下面的示例中,我们将 maxHeight 传递为 null,将宽度设置为 *300*,结果是宽度为 300 像素的缩放图片。

IImageInfo imgLarge = img.ResizeMe(null, 300);

下一行再次调用 Save 方法,但这次我们传递了我们想要保存图片的路径。在这种情况下,我们希望缩放后的图片位于“uploadedImages/large”目录中。

imgLarge.Save("uploadedImages/large");

(**注意:我们也可以在 imgLarge 变量的现有 Path 属性前加上“/large”,如下图所示,然后调用 Save())

imgLarge.Path += "/large";

下一节执行与上面相同的缩放操作,但这次通过设置 maxHeight 而不是 maxWidth 来缩放图片。

IImageInfo imgMedium = img.ResizeMe(185, null);
imgMedium.Save("uploadedImages/medium");

好了,这就是基本示例。然而,你并不总是以这种方式保存图片;很多时候,它们需要与数据库中的特定记录关联,或者以特定的方式命名。让我们看看在其他一些情况下我们可以怎么做。

其他示例

在下面的代码示例中,我们将首先将图片指针保存在数据库中,然后使用新的 ID 作为图片文件名。

//get uploaded image
IImageInfo img = WebManager.GetImageInfo(fileUploader);
string[] fileNameParts = img.FileName.split('.');
string fileExtension = fileNameParts.GetValue((fileNameParts.Length - 1));

Photo p = new Photo();
p.ProductID = 1;    //tie it to a product
p.Path = "uploadedImages/photos";
p.Description = "Left side view";
p.FileExtension = fileExtension;
ProductRepository.Save(p);

int newID = p.PhotoID;

img.Path = p.Path;
img.FileName = string.Format("{0}.{1}", newID.ToString(), p.FileExtension);
img.Save();

//save thumbnail versions
img.ResizeMe(null, 185).Save(p.Path += "/large");
img.ResizeMe(null, 100).Save(p.Path += "/medium");
img.ResizeMe(null, 50).Save(p.Path += "/small");

上面的示例展示了当保存产品照片时,这个库如何使事情变得更简单。在该示例中,我们首先将记录保存到数据库,然后使用记录创建时生成的唯一 ID 将图片保存到文件系统。现在,当我们想显示这张产品照片时,我们只需指向“uploadedImages/photos/[PhotoID].[FileExtension]”文件。如果需要较小的图片,只需指向“large”、“medium”或“small”子文件夹下的图片。

那么,根据上面的示例,如果我们想删除一个照片怎么办?最好能同时从文件系统中删除原始图片以及生成的所有缩略图。幸运的是,我们可以通过几种不同的方式来做到这一点。要删除上面示例中创建的图片,你可以这样做:

Photo p = PhotoRepository.GetPhotoByID(id);

//first, delete the images
string[] pathsToDeleteFrom = new string[] { p.Path, p.Path += 
  "/large", p.Path += "/medium", p.Path += "/small" };
WebManager.DeleteImageSetFromFileSystem(string.Format("{0}.{1}", 
  p.PhotoID.ToString(), p.FileExtension), pathsToDeleteFrom);

//now delete the database record
PhotoRepository.Delete(p);

DeleteImageSetFromFileSystem 方法接收文件名和要从中删除该文件的路径(目录)的字符串数组。因此,在此示例中,该照片的 PhotoID 文件名将从字符串数组中的每个路径中删除。

结论

好了,这就是对该库的快速概览。希望你觉得它很有用。我希望将来能更新更多功能,并在发布时在此处发布。

非常欢迎任何反馈/建议!

© . All rights reserved.