使用.NET C#定义宽度创建缩略图

4

我在我的网站中使用以下代码来创建缩略图:

string furl = "~/images/thumbs/" + matchString;
lBlogThumb.ImageUrl = GetThumbnailView(furl, 200, 200);


private string GetThumbnailView(string originalImagePath, int height, int width)
        {
            //Consider Image is stored at path like "ProductImage\\Product1.jpg"

            //Now we have created one another folder ProductThumbnail to store thumbnail image of product.
            //So let name of image be same, just change the FolderName while storing image.
            string thumbnailImagePath = originalImagePath.Replace("thumbs", "thumbs2");
            //If thumbnail Image is not available, generate it.
            if (!System.IO.File.Exists(Server.MapPath(thumbnailImagePath)))
            {
                System.Drawing.Image imThumbnailImage;
                System.Drawing.Image OriginalImage = System.Drawing.Image.FromFile(Server.MapPath(originalImagePath));
                imThumbnailImage = OriginalImage.GetThumbnailImage(width, height,
                             new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero);

                imThumbnailImage.Save(Server.MapPath(thumbnailImagePath), System.Drawing.Imaging.ImageFormat.Jpeg);

                imThumbnailImage.Dispose();
                OriginalImage.Dispose();
            }
            return thumbnailImagePath;
        }

public bool ThumbnailCallback() { return false; }

我希望修改这段代码,仅通过指定宽度来创建缩略图。我的想法实际上是像裁剪/缩放图像一样,使用固定宽度并保持其比例。这可能吗?


1
这是您想要的吗?newHeight = oldHeight * newWidth / oldWidth,不确定您说要裁剪图像时是什么意思 - 您是否想要裁剪并调整大小? - James Gaunt
我不知道为什么,但这给了我一个“内存不足”的错误..有没有人可以为此放置一个例外?我真的不知道C#如何处理内存。 - Berker Yüceer
@BerkerYüceer 这个问题已经存在好几年了,但你遇到这个错误很可能是因为你需要将 int(即 Image.HeightImage.Width)转换为浮点数类型之一。我建议使用 decimal - OneHoopyFrood
4个回答

15

你提到了缩放和裁剪。如果你想要生成的缩略图高度随着固定宽度变化,那么已经提供的答案可以满足你的需求。

如果你提到的裁剪意味着你想要一个固定的缩略图大小,并以填充宽度并裁剪任何溢出的垂直部分为目的,那么你需要做更多的工作。我最近也需要类似的东西,这就是我想出来的方法。

这将创建一个源图像完全填充目标缩略图并裁剪任何溢出的方式大小和裁剪后的原始图像缩略图。即使原始图像和缩略图的长宽比不同,缩略图内也不会有边框。

public System.Drawing.Image CreateThumbnail(System.Drawing.Image image, Size thumbnailSize)
{
    float scalingRatio = CalculateScalingRatio(image.Size, thumbnailSize);

    int scaledWidth = (int)Math.Round((float)image.Size.Width * scalingRatio);
    int scaledHeight = (int)Math.Round((float)image.Size.Height * scalingRatio);
    int scaledLeft = (thumbnailSize.Width - scaledWidth) / 2;
    int scaledTop = (thumbnailSize.Height - scaledHeight) / 2;

    // For portrait mode, adjust the vertical top of the crop area so that we get more of the top area
    if (scaledWidth < scaledHeight && scaledHeight > thumbnailSize.Height)
    {
        scaledTop = (thumbnailSize.Height - scaledHeight) / 4;
    }

    Rectangle cropArea = new Rectangle(scaledLeft, scaledTop, scaledWidth, scaledHeight);

    System.Drawing.Image thumbnail = new Bitmap(thumbnailSize.Width, thumbnailSize.Height);
    using (Graphics thumbnailGraphics = Graphics.FromImage(thumbnail))
    {
        thumbnailGraphics.CompositingQuality = CompositingQuality.HighQuality;
        thumbnailGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        thumbnailGraphics.SmoothingMode = SmoothingMode.HighQuality;
        thumbnailGraphics.DrawImage(image, cropArea);
    }
    return thumbnail;
}

private float CalculateScalingRatio(Size originalSize, Size targetSize)
{
    float originalAspectRatio = (float)originalSize.Width / (float)originalSize.Height;
    float targetAspectRatio = (float)targetSize.Width / (float)targetSize.Height;

    float scalingRatio = 0;

    if (targetAspectRatio >= originalAspectRatio)
    {
        scalingRatio = (float)targetSize.Width / (float)originalSize.Width;
    }
    else
    {
        scalingRatio = (float)targetSize.Height / (float)originalSize.Height;
    }

    return scalingRatio;
}

要在您的代码中使用,您可以将对 OriginalImage.GetThumbnailImage 的调用替换为以下内容:

imThumbnailImage = CreateThumbnail(OriginalImage, new Size(width, height));
请注意,对于竖直方向的图像,此代码实际上会在原始图像上将缩略图的视口稍微向上移动一些。这是为了在创建缩略图时,人物肖像照片不会出现没有头部的身体。如果您不想要这种逻辑,请删除“竖屏模式”注释后面的 if 代码块即可。

8

让我们假设原始宽度和缩略图宽度相同。您可以简单地选择所需的缩略图宽度,并计算thumbHeigth=originalHeigth*thumbWidth/originalWidth


1
我厌倦了需要这样做,于是创建了一个库,可以轻松地完成这个任务:文档链接和下载

这张图片有些不适宜在工作场合查看。 - Mihir

0

一个基本的示例,缩略图宽度为140,不进行四舍五入。在下面的“file”之下是从ASP.Net FileUpload控件上传的HttpPostedFile,HttpPostedFile公开了一个流。

// Save images to disk.
using (System.Drawing.Image image = System.Drawing.Image.FromStream(file.InputStream))
using (System.Drawing.Image thumbnailImage = image.GetThumbnailImage(140, Convert.ToInt32((image.Height / (image.Width / 140))), null, IntPtr.Zero))
{
    if (image != null)
    {
        image.Save(imageFilePath);
        thumbnailImage.Save(thumbnailImagePath); 
    }
    else
        throw new ArgumentNullException("Image stream is null");
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接