我有一个Web应用程序,允许用户上传各种格式的图像(PNG,JPEG,GIF)。不幸的是,我的用户不一定具备技术知识,最终上传了比所需质量和大小高得多的图像。
是否有办法在提供服务时压缩这些图像?通过压缩,我指的是有损压缩,降低质量而不一定是大小。如果不同的格式压缩方式不同,那我应该存储文件格式吗?
我有一个Web应用程序,允许用户上传各种格式的图像(PNG,JPEG,GIF)。不幸的是,我的用户不一定具备技术知识,最终上传了比所需质量和大小高得多的图像。
是否有办法在提供服务时压缩这些图像?通过压缩,我指的是有损压缩,降低质量而不一定是大小。如果不同的格式压缩方式不同,那我应该存储文件格式吗?
当然,您可以使用C#和.NET实时压缩图像。
这里有一个函数可以实现此功能。首先,它设置了一个类型为jpg的Encoder
对象,并向其添加一个新质量参数。然后将该对象用于将具有新质量的图像写入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;
}
这是一个使用 .net 4.0 编写的小应用程序,可以实时压缩图像。 也许它能帮到你 https://github.com/user5934951/CompressImageLiveNet
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;
}
}