议题

用户上传到网站上的大多数的图片都是大尺寸的照片,通常在用户想看完整图片之前网站会展示出这些图片或照片的缩略图。

解决方案

使用以下的类来调整上传的图片文件的宽和高:FileStream,Image,Bitmap和Graphics。

讨论

在下面的示例中,将修改和重组之前创建的FileUpload类。创建一个新的称为“ResizeImage”的方法来调整图片大小。调整之后的图片文件将被保存到源文件存储文件夹的子文件夹“Thumbnails”中。同时也要修改DeleteFile方法,添加同时删除原始图像和缩略图,并且为了避免重复代码要创建一个新的删除功能的方法。下面显示变化部分的类代码:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace MvcApplication4.Utils
{
public static class FileUpload
    {
public static char DirSeparator =
        System.IO.Path.DirectorySeparatorChar;
public static string FilesPath = "Content" +
        DirSeparator + "Uploads" + DirSeparator;
public static string UploadFile(HttpPostedFileBase file)
        {
            ...
// 保存缩略图
            ResizeImage(file, 150, 100);
            ...
        }
public static void DeleteFile(string fileName)
        {
// 如果没有指定文件名就什么都不做
            if (fileName.Length == 0) return;
// 设置删除路径
            string path = FilesPath + DirSeparator + fileName;
string thumbPath = FilesPath + DirSeparator +
"Thumbnails" + DirSeparator + fileName;
            RemoveFile(path);
            RemoveFile(thumbPath);
        }
private static void RemoveFile(string path)
        {
// 检查文件是否存在
            if (File.Exists(Path.GetFullPath(path)))
            {
// 删除文件
                File.Delete(Path.GetFullPath(path));
            }
        }
public static void ResizeImage(HttpPostedFileBase file,
int width, int height)
        {
string thumbnailDirectory =
            String.Format(@"{0}{1}{2}", FilesPath,
            DirSeparator, "Thumbnails");
// 检查目标文件夹是否存在
            if (!Directory.Exists(thumbnailDirectory))
            {
// 假如文件夹不存在就创建它
                Directory.CreateDirectory(thumbnailDirectory);
            }
// 设置缩略图保存路径
            string imagePath =
            String.Format(@"{0}{1}{2}", thumbnailDirectory,
            DirSeparator, file.FileName);
// 将文件流保存到磁盘
            FileStream stream = new FileStream(Path.GetFullPath(
            imagePath), FileMode.OpenOrCreate);
// 缩放上传的文件
            Image OrigImage = Image.FromStream(file.InputStream);
// 创建缩略图对象
            Bitmap TempBitmap = new Bitmap(width, height);
// 创建缩略图画质
            Graphics NewImage = Graphics.FromImage(TempBitmap);
            NewImage.CompositingQuality =
            CompositingQuality.HighQuality;
            NewImage.SmoothingMode =
            SmoothingMode.HighQuality;
            NewImage.InterpolationMode =
            InterpolationMode.HighQualityBicubic;
// 创建Rectangle对象进行绘制
            Rectangle imageRectangle = new Rectangle(0, 0,
            width, height);
            NewImage.DrawImage(OrigImage, imageRectangle);
// 保存缩略图
            TempBitmap.Save(stream, OrigImage.RawFormat);
// 释放资源
            NewImage.Dispose();
            TempBitmap.Dispose();
            OrigImage.Dispose();
            stream.Close();
            stream.Dispose();
        }
    }
}



在上面的示例中,我们做了许多修改,特别创建ResizeImage方法。首先,判断“Thumbnails”文件夹是否存在以及创建功能。接下来,会创建一个新的FileStream对象,并将编辑后的图片保存到“Thumbnails”文件夹中。 

从提交的InputStream创建原始图片对象。然后基于缩略图的尺寸创建缩略图的Bitmap位图实例。然后基于这个Bitmap对象创建新的Graphics对象,然后设置图像的画质、平滑度、插值模式,如果不设置这些值,缩略图会因为很像素化和比例变形变的很难看。 

将这些值都设置完毕,创建一个原始尺寸的Recangle对象,将这个对象缩放后绘制到之前创建的Graphics对象中,这时才实际调整尺寸。最后保存Bitmap对象,释放所有资源。