如何在 C# 中进行动态图像压缩?

use*_*724 5 c# compression performance image

我有一个网络应用程序,允许用户上传各种格式的图像(PNG、JPEG、GIF)。不幸的是,我的用户不一定是技术人员,最终上传的图像质量(和大小)比所需的要高。

有没有办法让我在提供这些图像时对其进行压缩?我所说的压缩是指有损压缩,即降低质量,但不一定降低大小。如果不同格式的压缩方式不同,我是否也应该存储文件格式?

TaW*_*TaW 10

当然,您可以使用 C# 和 .NET 动态压缩图像。

这是一个执行此操作的函数。首先,它设置一个Encoderjpg 类型的对象,并向其中添加一个用于新质量的参数。然后将其用于将具有新质量的图像写入MemoryStream.

然后,从该流创建的图像将以新的尺寸绘制到自身上......:

//..
using System.Drawing.Imaging;
using System.IO;
//..

private Image compressImage(string fileName,  int newWidth, int newHeight, 
                            int newQuality)   // set quality to 1-100, eg 50
{
    using (Image image = Image.FromFile(fileName))
    using (Image memImage= new Bitmap(image, newWidth, newHeight))  
    {
        ImageCodecInfo myImageCodecInfo;
        System.Drawing.Imaging.Encoder myEncoder;
        EncoderParameter myEncoderParameter;
        EncoderParameters myEncoderParameters;
        myImageCodecInfo = GetEncoderInfo("image/jpeg"); 
        myEncoder = System.Drawing.Imaging.Encoder.Quality;
        myEncoderParameters = new EncoderParameters(1);
        myEncoderParameter = new EncoderParameter(myEncoder, newQuality);
        myEncoderParameters.Param[0] = myEncoderParameter;

        MemoryStream memStream = new MemoryStream();
        memImage.Save(memStream, myImageCodecInfo, myEncoderParameters);
        Image newImage = Image.FromStream(memStream);
        ImageAttributes imageAttributes = new ImageAttributes();
        using (Graphics g = Graphics.FromImage(newImage))
        {
            g.InterpolationMode = 
              System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;  //**
            g.DrawImage(newImage,  new Rectangle(Point.Empty, newImage.Size), 0, 0, 
              newImage.Width, newImage.Height, GraphicsUnit.Pixel, imageAttributes);
        }
        return newImage;
    }
}

private static ImageCodecInfo GetEncoderInfo(String mimeType)
{
    ImageCodecInfo[] encoders;
    encoders = ImageCodecInfo.GetImageEncoders();
    foreach (ImageCodecInfo ici in encoders)
        if (ici.MimeType == mimeType) return ici;

    return null;
}
Run Code Online (Sandbox Code Playgroud)

设置新尺寸由您决定。如果您不想更改尺寸,请取出参数并将值设置为代码块中的旧尺寸如果您只是有时想更改,可以将它们作为 0 或 -1 传递并在内部进行检查。

质量应在 30-60% 左右,具体取决于主题。带文本的屏幕截图不能很好地缩小,需要大约 60-80% 才能看起来漂亮且清晰。

此函数返回文件的 jpeg 版本。如果需要,您可以创建不同的编码器,但对于可扩展的质量,jpeg 通常是最佳选择。

显然,您也可以传入图像而不是文件名,或者将 newImage 保存到磁盘而不是返回它。(在这种情况下,您应该将其丢弃。)

另外:您可以检查memStream.Length结果是否太大并调整质量。

编辑:更正//**