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

如何在C#中进行动态图像压缩?,c#,image,performance,compression,C#,Image,Performance,Compression,我有一个web应用程序,允许用户上传各种格式的图像(PNG、JPEG、GIF)。不幸的是,我的用户不一定是技术性的,最终上传的图像质量(和大小)都比要求的高 在提供这些图像时,有没有办法压缩它们?我所说的压缩是指有损压缩,降低了质量,而不一定是尺寸。如果不同格式的压缩方式不同,我是否也应该存储文件格式?当然,您可以使用C#和.NET动态压缩图像 这里有一个这样做的函数。首先,它设置一个jpg类型的编码器对象,并为其添加一个新质量参数。然后使用它将具有新质量的图像写入MemoryStream 然后

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


在提供这些图像时,有没有办法压缩它们?我所说的压缩是指有损压缩,降低了质量,而不一定是尺寸。如果不同格式的压缩方式不同,我是否也应该存储文件格式?

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

这里有一个这样做的函数。首先,它设置一个jpg类型的
编码器
对象,并为其添加一个新质量参数。然后使用它将具有新质量的图像写入
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;
}
设置新尺寸取决于您。如果您永远不想更改维度,请取出参数并将值设置为代码块中的旧维度如果您只是偶尔想更改,可以将它们作为0或-1传入,并在内部执行检查

质量应在30-60%左右,取决于图案。带有文本的屏幕截图不能很好地缩小比例,需要60-80%左右的比例才能看起来美观、酥脆

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

显然,您也可以传入一个图像而不是文件名,或者将新图像保存到磁盘而不是返回它。(那样的话,你应该把它处理掉。)

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

编辑:更正/**

使用系统;
使用System.Collections.Generic;
使用系统图;
使用系统、绘图、成像;
使用System.IO;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
名称空间导出
{
班级计划
{
静态void Main(字符串[]参数)
{
foreach(目录中的字符串文件。枚举文件(@“C:\Temp\Images”))
{
FileInfo file\u info=新的FileInfo(文件);
var filePathOriginal=Path.Combine(@“C:\Temp\Images”,
格式(“{0}”,文件名));
if(File.Exists(filePathOriginal)&&File_info.Name.Contains(“.png”))
{
Task.Factory.StartNew(()=>VaryQualityLevel(filePathOriginal));
WriteLine(“压缩的{0}.{1}”,计数,文件名);
计数++;
}
}            
WriteLine(“结束压缩{0}图像{2}{2}日期:{1}{2}”,计数,日期时间.Now,环境.NewLine);
控制台。写入线(“完成”);
Console.ReadLine();
}
静态void varyqualityvel(字符串文件)
{
var img=新位图(文件);
尝试
{
SaveJpeg(img,文件);
img.Dispose();
如果(File.Exists(File))
文件。删除(文件);
文件移动(文件+1,文件);
}
捕获(例外情况除外)
{
//继续
}
}
静态void SaveJpeg(图像img,字符串文件名)
{
编码器参数qualityParam=新编码器参数(编码器质量,100L);
ImageCodeInfo jpegCodec=GetEncoder(ImageFormat.Jpeg);
EncoderParameters encoderParams=新的EncoderParameters(1);
encoderParams.Param[0]=qualityParam;
保存(文件名+1,JPEG编解码器,编码器参数);
}
静态ImageCodeInfo GetEncoder(ImageFormat格式)
{
ImageCodecInfo[]codecs=ImageCodecInfo.GetImageDecoders();
foreach(编解码器中的ImageCodeInfo编解码器)
{
if(codec.FormatID==format.Guid)
{
返回编解码器;
}
}
返回null;
}

}
这是一个用.net 4.0编写的小型应用程序,可在live中压缩图像。 也许会有帮助

确实有很多图像处理库-查找它…还可以尝试开始编写小代码,动态地将图像大小调整到某个固定大小(在.Net中已经有了所有内容,不同于具有不同质量的压缩)并查看它是否/如何适合您的应用程序。如果我理解正确,这可以接受PNG、JPEG和GIF格式,但会返回JPEG格式,对吗?如果是,我认为这可能满足我的需要。事实上。它还可以接受TIF文件或BMP格式:请看,您知道您昨天将一个问题标记为完全相同的问题,而这是一个完全不同的问题,right?不是。问题是:如何确保jpeg在保存时不会增长而会收缩。在一篇评论中,我告诉海报,他需要添加一个显式编码器,以便控制压缩。下面是一个如何做到这一点的示例。@TaW好的,那么你在哪里显示你的.Save()上面的方法调用?因为这就是另一个人的问题所在。如果您忘记了,请发布URL:他的文件变大的原因是位图的.Save()方法默认为PNG格式。即使您的答案是jpg文件,对于大多数人来说,指定Imaging.ImageFormat.Jpeg就足够了?