我有一个网络应用程序,允许用户上传各种格式的图像(PNG,JPEG,GIF)。不幸的是,我的用户不一定是技术人员,最终会上传质量(和尺寸)超出要求的图片。
有没有办法让我在服务时压缩这些图像?通过压缩我的意思是有损压缩,降低质量而不一定是尺寸。如果不同的格式压缩不同,我是否应该存储文件格式?
答案 0 :(得分:2)
当然,您可以使用C#和.NET动态压缩图像。
这是一个这样做的功能。首先,它设置jpg类型的Encoder
对象,并为其添加一个新quailty参数。然后将其用于将图像的新质量写入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 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传递给内部进行检查.. < / p>
质量应该在30-60%左右,具体取决于图案。带有文字的屏幕截图不能很好地缩小,需要大约60-80%才能看起来很好而且很脆。
此函数返回文件的jpeg版本。如果你愿意,你可以创建一个不同的编码器,但为了可扩展的质量,jpeg通常是最好的选择。
显然你也可以传入图像而不是文件名,或者将newImage保存到磁盘而不是返回它。 (在这种情况下你应该处理它。)
另外:您可以查看memStream.Length
以查看结果是否过大并调整质量。
编辑:更正// **
答案 1 :(得分:0)
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace export
{
class Program
{
static void Main(string[] args)
{
foreach (string file in Directory.EnumerateFiles(@"C:\Temp\Images"))
{
FileInfo file_info = new FileInfo(file);
var filePathOriginal = Path.Combine(@"C:\Temp\Images",
String.Format("{0}", file_info.Name));
if (File.Exists(filePathOriginal) && file_info.Name.Contains(".png"))
{
Task.Factory.StartNew(() => VaryQualityLevel(filePathOriginal));
Console.WriteLine("Compressed {0}. {1}", count, file_info.Name);
count++;
}
}
Console.WriteLine("End Compressing {0} Images{2}{2}Date: {1}{2}", count, DateTime.Now, Environment.NewLine);
Console.WriteLine("Done");
Console.ReadLine();
}
static void VaryQualityLevel(string file)
{
var img = new Bitmap(file);
try
{
SaveJpeg(img, file);
img.Dispose();
if (File.Exists(file))
File.Delete(file);
File.Move(file + 1, file);
}
catch (Exception ex)
{
// Keep going
}
}
static void SaveJpeg(Image img, string filename)
{
EncoderParameter qualityParam = new EncoderParameter(Encoder.Quality, 100L);
ImageCodecInfo jpegCodec = GetEncoder(ImageFormat.Jpeg);
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
img.Save(filename + 1, jpegCodec, encoderParams);
}
static ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}
}
答案 2 :(得分:0)
这是一个用.net 4.0编写的小型应用程序,可以实时压缩图像。 也许可以帮上忙 https://github.com/user5934951/CompressImageLiveNet
答案 3 :(得分:-5)
使用IIS或Apache压缩。它适用于两个Web服务器。