如何在C#中进行快速图像压缩? [英] How to do on the fly image compression in C#?

查看:202
本文介绍了如何在C#中进行快速图像压缩?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Web应用程序,允许用户上传各种格式的图像(PNG,JPEG,GIF)。不幸的是,我的用户不一定是技术人员,最终会上传质量(和尺寸)超出要求的图像。

I have a web application that allows users to upload images of various formats (PNG, JPEG, GIF). Unfortunately my users are not necessarily technical and end up uploading images that are of way too high quality (and size) than is required.

有没有办法让我压缩为他们服务时这些图片?通过压缩我的意思是有损压缩,降低质量而不一定是尺寸。如果不同的格式压缩不同,我是否应该存储文件格式?

Is there a way for me to compress these images when serving them? By compress I mean lossy compression, reducing the quality and not necessarily the size. Should I be storing the file format as well if different formats are compressed differently?

推荐答案

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

Of course you can compress images on the fly using C# and .NET.

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

Here is a function to do so. First it sets up an Encoder object of type jpg and adds one parameter for the new quailty to it. This is then used to write the image with its new quality to a MemoryStream.

然后从中创建一个图像使用System.Drawing.Imaging将流绘制到自身的新维度..:

Then an image created from that stream is drawn onto itself with the new dimensions..:

//..
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 int 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并在内部进行检查..

Setting the new dimensions is up to you. If you never want to change the dimensions, take out the parameters and set the values to the old dimensions in the code block If you only sometimes want to change you could pass them in as 0 or -1 and do the check inside..

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

Quality should be around 30-60%, depending on the motifs. Screenshots with text don't scale down well and need around 60-80% to look good and crispy.

此函数返回文件的jpeg版本。如果你愿意,你可以创建一个不同的编码器,但是为了可扩展的质量,jpeg通常是最好的选择。

This function returns a jpeg version of the file. If you want, you could create a different Encoder, but for scalable quality, jpeg usually is the best choice.

显然你也可以传入图像而不是filename或将newImage保存到磁盘而不是返回它。 (在这种情况下你应该处理它。)

Obviously you could as well pass in an image instead of a filename or save the newImage to disk instead of returning it. (You should dispose of it in that case.)

另外:你可以查看 memStream.Length 来查看如果结果太大并调整质量..

Also: you could check the memStream.Length to see if the results are too big and adjust the quality..

编辑:更正// **

这篇关于如何在C#中进行快速图像压缩?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆