【问题标题】:Create thumbnail image创建缩略图
【发布时间】:2011-02-18 00:42:12
【问题描述】:

我想在文件位置的网格视图中显示缩略图。如何生成.jpeg 文件? 我正在使用C# 语言和asp.net

【问题讨论】:

标签: c# asp.net gridview thumbnails


【解决方案1】:

你必须在Image类中使用GetThumbnailImage方法:

https://msdn.microsoft.com/en-us/library/8t23aykb%28v=vs.110%29.aspx

这是一个粗略的示例,它获取图像文件并从中制作缩略图,然后将其保存回磁盘。

Image image = Image.FromFile(fileName);
Image thumb = image.GetThumbnailImage(120, 120, ()=>false, IntPtr.Zero);
thumb.Save(Path.ChangeExtension(fileName, "thumb"));

它在 System.Drawing 命名空间中(在 System.Drawing.dll 中)。

行为:

如果 Image 包含嵌入的缩略图,此方法 检索嵌入的缩略图并将其缩放到请求的大小。 如果 Image 不包含嵌入的缩略图,则此方法 通过缩放主图像创建缩略图。


重要提示:上述 Microsoft 链接的备注部分警告某些潜在问题:

GetThumbnailImage 方法在请求缩略图时效果很好 图像的大小约为 120 x 120 像素。如果您要求大 缩略图(例如,300 x 300)来自具有 嵌入的缩略图,可能会出现明显的质量损失 缩略图

缩放主图像可能会更好(而不是 通过调用DrawImage 方法来缩放嵌入的缩略图)。

【讨论】:

  • 一般只能用于JPG图片。如果您尝试像这样调整 PNG 图像的大小,则会收到此错误。
  • 真的,用它来获取全高清照片的 400x225 缩略图,生成的“缩略图”大小为 200 kB(原始 350 kB)。这种方法是要避免的。
  • @NathanaelJones,你是认真的吗? ImageResizer 对企业来说不是免费的。
【解决方案2】:

以下代码将根据响应写入一个图像,您可以根据自己的目的修改代码:

public void WriteImage(string path, int width, int height)
{
    Bitmap srcBmp = new Bitmap(path);
    float ratio = srcBmp.Width / srcBmp.Height;
    SizeF newSize = new SizeF(width, height * ratio);
    Bitmap target = new Bitmap((int) newSize.Width,(int) newSize.Height);
    HttpContext.Response.Clear();
    HttpContext.Response.ContentType = "image/jpeg";
    using (Graphics graphics = Graphics.FromImage(target))
    {
        graphics.CompositingQuality = CompositingQuality.HighSpeed;
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        graphics.CompositingMode = CompositingMode.SourceCopy;
        graphics.DrawImage(srcBmp, 0, 0, newSize.Width, newSize.Height);
        using (MemoryStream memoryStream = new MemoryStream()) 
        {
            target.Save(memoryStream, ImageFormat.Jpeg);
            memoryStream.WriteTo(HttpContext.Response.OutputStream);
        }
    }
    Response.End();
}

【讨论】:

  • 我在字符串路径中给出了我的本地文件路径。它返回“不支持给定的路径格式”。
  • 我给了这样的... var path = @"C:\Users\Gopal\Desktop\files.jpeg";位图 srcBmp = 新位图(路径);
  • 对于那些使用HttpResponseMessage的人:response.Content = new ByteArrayContent(memoryStream.ToArray());
  • 小心,此代码假定图像是“水平的”(横向)
【解决方案3】:

这是一个如何创建较小图像(缩略图)的完整示例。这个 sn-p 调整图像的大小,在需要时旋转它(如果垂直握住手机)并填充图像,如果你想创建方形拇指。这个 sn-p 创建一个 JPEG,但它可以很容易地修改为其他文件类型。即使图像小于允许的最大尺寸,图像仍会被压缩,并且会更改其分辨率以创建具有相同 dpi 和压缩级别的图像。

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;

//set the resolution, 72 is usually good enough for displaying images on monitors
float imageResolution = 72;

//set the compression level. higher compression = better quality = bigger images
long compressionLevel = 80L;


public Image resizeImage(Image image, int maxWidth, int maxHeight, bool padImage)
{
    int newWidth;
    int newHeight;

    //first we check if the image needs rotating (eg phone held vertical when taking a picture for example)
    foreach (var prop in image.PropertyItems)
    {
        if (prop.Id == 0x0112)
        {
            int orientationValue = image.GetPropertyItem(prop.Id).Value[0];
            RotateFlipType rotateFlipType = getRotateFlipType(orientationValue);
            image.RotateFlip(rotateFlipType);
            break;
        }
    }

    //apply the padding to make a square image
    if (padImage == true)
    {
        image = applyPaddingToImage(image, Color.Red);
    }

    //check if the with or height of the image exceeds the maximum specified, if so calculate the new dimensions
    if (image.Width > maxWidth || image.Height > maxHeight)
    {
        double ratioX = (double)maxWidth / image.Width;
        double ratioY = (double)maxHeight / image.Height;
        double ratio = Math.Min(ratioX, ratioY);

        newWidth = (int)(image.Width * ratio);
        newHeight = (int)(image.Height * ratio);
    }
    else
    {
        newWidth = image.Width;
        newHeight = image.Height;
    }

    //start the resize with a new image
    Bitmap newImage = new Bitmap(newWidth, newHeight);

    //set the new resolution
    newImage.SetResolution(imageResolution, imageResolution);

    //start the resizing
    using (var graphics = Graphics.FromImage(newImage))
    {
        //set some encoding specs
        graphics.CompositingMode = CompositingMode.SourceCopy;
        graphics.CompositingQuality = CompositingQuality.HighQuality;
        graphics.SmoothingMode = SmoothingMode.HighQuality;
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

        graphics.DrawImage(image, 0, 0, newWidth, newHeight);
    }

    //save the image to a memorystream to apply the compression level
    using (MemoryStream ms = new MemoryStream())
    {
        EncoderParameters encoderParameters = new EncoderParameters(1);
        encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, compressionLevel);

        newImage.Save(ms, getEncoderInfo("image/jpeg"), encoderParameters);

        //save the image as byte array here if you want the return type to be a Byte Array instead of Image
        //byte[] imageAsByteArray = ms.ToArray();
    }

    //return the image
    return newImage;
}


//=== image padding
public Image applyPaddingToImage(Image image, Color backColor)
{
    //get the maximum size of the image dimensions
    int maxSize = Math.Max(image.Height, image.Width);
    Size squareSize = new Size(maxSize, maxSize);

    //create a new square image
    Bitmap squareImage = new Bitmap(squareSize.Width, squareSize.Height);

    using (Graphics graphics = Graphics.FromImage(squareImage))
    {
        //fill the new square with a color
        graphics.FillRectangle(new SolidBrush(backColor), 0, 0, squareSize.Width, squareSize.Height);

        //put the original image on top of the new square
        graphics.DrawImage(image, (squareSize.Width / 2) - (image.Width / 2), (squareSize.Height / 2) - (image.Height / 2), image.Width, image.Height);
    }

    //return the image
    return squareImage;
}


//=== get encoder info
private ImageCodecInfo getEncoderInfo(string mimeType)
{
    ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();

    for (int j = 0; j < encoders.Length; ++j)
    {
        if (encoders[j].MimeType.ToLower() == mimeType.ToLower())
        {
            return encoders[j];
        }
    }

    return null;
}


//=== determine image rotation
private RotateFlipType getRotateFlipType(int rotateValue)
{
    RotateFlipType flipType = RotateFlipType.RotateNoneFlipNone;

    switch (rotateValue)
    {
        case 1:
            flipType = RotateFlipType.RotateNoneFlipNone;
            break;
        case 2:
            flipType = RotateFlipType.RotateNoneFlipX;
            break;
        case 3:
            flipType = RotateFlipType.Rotate180FlipNone;
            break;
        case 4:
            flipType = RotateFlipType.Rotate180FlipX;
            break;
        case 5:
            flipType = RotateFlipType.Rotate90FlipX;
            break;
        case 6:
            flipType = RotateFlipType.Rotate90FlipNone;
            break;
        case 7:
            flipType = RotateFlipType.Rotate270FlipX;
            break;
        case 8:
            flipType = RotateFlipType.Rotate270FlipNone;
            break;
        default:
            flipType = RotateFlipType.RotateNoneFlipNone;
            break;
    }

    return flipType;
}


//== convert image to base64
public string convertImageToBase64(Image image)
{
    using (MemoryStream ms = new MemoryStream())
    {
        //convert the image to byte array
        image.Save(ms, ImageFormat.Jpeg);
        byte[] bin = ms.ToArray();

        //convert byte array to base64 string
        return Convert.ToBase64String(bin);
    }
}

为 asp.net 用户提供一个关于如何上传文件、调整文件大小并在页面上显示结果的小示例。

//== the button click method
protected void Button1_Click(object sender, EventArgs e)
{
    //check if there is an actual file being uploaded
    if (FileUpload1.HasFile == false)
    {
        return;
    }

    using (Bitmap bitmap = new Bitmap(FileUpload1.PostedFile.InputStream))
    {
        try
        {
            //start the resize
            Image image = resizeImage(bitmap, 256, 256, true);

            //to visualize the result, display as base64 image
            Label1.Text = "<img src=\"data:image/jpg;base64," + convertImageToBase64(image) + "\">";

            //save your image to file sytem, database etc here
        }
        catch (Exception ex)
        {
            Label1.Text = "Oops! There was an error when resizing the Image.<br>Error: " + ex.Message;
        }
    }
}

【讨论】:

  • 我喜欢这个代码示例并选择使用它。但是,无论我对各种选项(imageResolution、compressionLevel、CompositingMode、CompositingQuality、SmoothingMode、InterpolationMode、PixelOffsetMode)做了什么更改,图像文件的大小都只减少了一小部分。而且我从未看到创建的图像有任何不同。最后,我选择将图像保存到文件而不是内存流中,并且能够看到剧烈的变化。对于任何使用它的人来说,保存到内存流似乎不会影响返回的图像。
【解决方案4】:

这是一个将高分辨率图像转换为缩略图大小的示例-

protected void Button1_Click(object sender, EventArgs e)
{
    //----------        Getting the Image File
    System.Drawing.Image img = System.Drawing.Image.FromFile(Server.MapPath("~/profile/Avatar.jpg"));

    //----------        Getting Size of Original Image
    double imgHeight = img.Size.Height;
    double imgWidth = img.Size.Width;

    //----------        Getting Decreased Size
    double x = imgWidth / 200;
    int newWidth = Convert.ToInt32(imgWidth / x);
    int newHeight = Convert.ToInt32(imgHeight / x);

    //----------        Creating Small Image
    System.Drawing.Image.GetThumbnailImageAbort myCallback = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
    System.Drawing.Image myThumbnail = img.GetThumbnailImage(newWidth, newHeight, myCallback, IntPtr.Zero);

    //----------        Saving Image
    myThumbnail.Save(Server.MapPath("~/profile/NewImage.jpg"));
}
public bool ThumbnailCallback()
{
    return false;
}

来源- http://iknowledgeboy.blogspot.in/2014/03/c-creating-thumbnail-of-large-image-by.html

【讨论】:

    【解决方案5】:

    这是基于已接受答案的版本。它解决了两个问题...

    1. 图像处理不当。
    2. 保持图像的纵横比。

    我发现这个工具对 JPG 和 PNG 文件都快速有效。

    private static FileInfo CreateThumbnailImage(string imageFileName, string thumbnailFileName)
    {
        const int thumbnailSize = 150;
        using (var image = Image.FromFile(imageFileName))
        {
            var imageHeight = image.Height;
            var imageWidth = image.Width;
            if (imageHeight > imageWidth)
            {
                imageWidth = (int) (((float) imageWidth / (float) imageHeight) * thumbnailSize);
                imageHeight = thumbnailSize;
            }
            else
            {
                imageHeight = (int) (((float) imageHeight / (float) imageWidth) * thumbnailSize);
                imageWidth = thumbnailSize;
            }
    
            using (var thumb = image.GetThumbnailImage(imageWidth, imageHeight, () => false, IntPtr.Zero))
                //Save off the new thumbnail
                thumb.Save(thumbnailFileName);
        }
    
        return new FileInfo(thumbnailFileName);
    }
    

    【讨论】:

      【解决方案6】:

      这是我正在使用的代码。也适用于 .NET Core > 2.0 使用 System.Drawing.Common NuGet。

      https://www.nuget.org/packages/System.Drawing.Common/

      using System;
      using System.Drawing;
      
      class Program
      {
          static void Main()
          {
              const string input = "C:\\background1.png";
              const string output = "C:\\thumbnail.png";
      
              // Load image.
              Image image = Image.FromFile(input);
      
              // Compute thumbnail size.
              Size thumbnailSize = GetThumbnailSize(image);
      
              // Get thumbnail.
              Image thumbnail = image.GetThumbnailImage(thumbnailSize.Width,
                  thumbnailSize.Height, null, IntPtr.Zero);
      
              // Save thumbnail.
              thumbnail.Save(output);
          }
      
          static Size GetThumbnailSize(Image original)
          {
              // Maximum size of any dimension.
              const int maxPixels = 40;
      
              // Width and height.
              int originalWidth = original.Width;
              int originalHeight = original.Height;
      
              // Return original size if image is smaller than maxPixels
              if (originalWidth <= maxPixels || originalHeight <= maxPixels)
              {
                  return new Size(originalWidth, originalHeight);
              }   
      
              // Compute best factor to scale entire image based on larger dimension.
              double factor;
              if (originalWidth > originalHeight)
              {
                  factor = (double)maxPixels / originalWidth;
              }
              else
              {
                  factor = (double)maxPixels / originalHeight;
              }
      
              // Return thumbnail size.
              return new Size((int)(originalWidth * factor), (int)(originalHeight * factor));
          }
      }
      

      来源:

      https://www.dotnetperls.com/getthumbnailimage

      【讨论】:

        猜你喜欢
        • 2012-03-19
        • 2012-02-04
        • 1970-01-01
        • 2014-09-07
        • 2015-09-16
        • 2014-09-24
        • 1970-01-01
        • 1970-01-01
        • 2018-10-31
        相关资源
        最近更新 更多