我做了一个小的C#应用程序来创建.jpg格式的图像。在C中保存JPG的质量#
pictureBox.Image.Save(name,ImageFormat.Jpeg);
图像被成功创建。我输入一张原始图片,用它做一些东西并保存。然而,这张新照片的质量比原来的低。
有没有什么方法可以设置所需的质量?
我做了一个小的C#应用程序来创建.jpg格式的图像。在C中保存JPG的质量#
pictureBox.Image.Save(name,ImageFormat.Jpeg);
图像被成功创建。我输入一张原始图片,用它做一些东西并保存。然而,这张新照片的质量比原来的低。
有没有什么方法可以设置所需的质量?
以下代码示例演示如何使用EncoderParameter构造函数创建EncoderParameter。要运行此示例,请粘贴代码并调用VaryQualityLevel
方法。
这个例子需要一个名为TestPhoto.jpg的图像文件位于c :.
private void VaryQualityLevel()
{
// Get a bitmap.
Bitmap bmp1 = new Bitmap(@"c:\TestPhoto.jpg");
ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);
// Create an Encoder object based on the GUID
// for the Quality parameter category.
System.Drawing.Imaging.Encoder myEncoder =
System.Drawing.Imaging.Encoder.Quality;
// Create an EncoderParameters object.
// An EncoderParameters object has an array of EncoderParameter
// objects. In this case, there is only one
// EncoderParameter object in the array.
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder,
50L);
myEncoderParameters.Param[0] = myEncoderParameter;
bmp1.Save(@"c:\TestPhotoQualityFifty.jpg", jgpEncoder,
myEncoderParameters);
myEncoderParameter = new EncoderParameter(myEncoder, 100L);
myEncoderParameters.Param[0] = myEncoderParameter;
bmp1.Save(@"c:\TestPhotoQualityHundred.jpg", jgpEncoder,
myEncoderParameters);
// Save the bitmap as a JPG file with zero quality level compression.
myEncoderParameter = new EncoderParameter(myEncoder, 0L);
myEncoderParameters.Param[0] = myEncoderParameter;
bmp1.Save(@"c:\TestPhotoQualityZero.jpg", jgpEncoder,
myEncoderParameters);
}
private ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}
编号:http://msdn.microsoft.com/en-us/library/system.drawing.imaging.encoderparameter.aspx
退房MSDN对how to set JPEG Compression level文章。
您需要使用另一个带有ImageEncoder及其参数的Save()重载。
这是一个古老的线程,但我已经重写了微软(按达斯汀·盖茨的回答)是一个小更实用 - 收缩GetEncoderInfo,使图像上的延伸。 反正没有什么新意,但可能是有用的:
/// <summary>
/// Retrieves the Encoder Information for a given MimeType
/// </summary>
/// <param name="mimeType">String: Mimetype</param>
/// <returns>ImageCodecInfo: Mime info or null if not found</returns>
private static ImageCodecInfo GetEncoderInfo(String mimeType)
{
var encoders = ImageCodecInfo.GetImageEncoders();
return encoders.FirstOrDefault(t => t.MimeType == mimeType);
}
/// <summary>
/// Save an Image as a JPeg with a given compression
/// Note: Filename suffix will not affect mime type which will be Jpeg.
/// </summary>
/// <param name="image">Image: Image to save</param>
/// <param name="fileName">String: File name to save the image as. Note: suffix will not affect mime type which will be Jpeg.</param>
/// <param name="compression">Long: Value between 0 and 100.</param>
private static void SaveJpegWithCompressionSetting(Image image, string fileName, long compression)
{
var eps = new EncoderParameters(1);
eps.Param[0] = new EncoderParameter(Encoder.Quality, compression);
var ici = GetEncoderInfo("image/jpeg");
image.Save(fileName, ici, eps);
}
/// <summary>
/// Save an Image as a JPeg with a given compression
/// Note: Filename suffix will not affect mime type which will be Jpeg.
/// </summary>
/// <param name="image">Image: This image</param>
/// <param name="fileName">String: File name to save the image as. Note: suffix will not affect mime type which will be Jpeg.</param>
/// <param name="compression">Long: Value between 0 and 100.</param>
public static void SaveJpegWithCompression(this Image image, string fileName, long compression)
{
SaveJpegWithCompressionSetting(image, fileName, compression);
}
如果您使用的是.NET Compact Framework的,另一种可能是使用PNG无损格式,即:
image.Save(filename, ImageFormat.Png);
这里是一个甚至代码更紧凑块用于为JPEG保存与特定的品质:
var encoder = ImageCodecInfo.GetImageEncoders().First(c => c.FormatID == ImageFormat.Jpeg.Guid);
var encParams = new EncoderParameters() { Param = new[] { new EncoderParameter(Encoder.Quality, 90L) } };
image.Save(path, encoder, encParams);
或者,如果120字符宽线过长给你:
var encoder = ImageCodecInfo.GetImageEncoders()
.First(c => c.FormatID == ImageFormat.Jpeg.Guid);
var encParams = new EncoderParameters(1);
encParams.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
image.Save(path, encoder, encParams);
确保质量是long
或者您将得到ArgumentException
!
进入我的代码库非常感谢你! – JustJohn 2017-03-26 20:24:20
另请参见[bytecode77的回答](https://stackoverflow.com/a/39493346/199364),该版本使用'using'确保'Dispose'在最后立即执行。 – ToolmakerSteve 2017-08-05 11:18:36
使用无类型的GDI +风格(https://msdn.microsoft.com/en-us/library/windows/desktop/ms533845(v=vs.85).aspx)属性设置JPEG质量看起来overkilling。
直接的方式应该是这样的:
FileStream stream = new FileStream("new.jpg", FileMode.Create);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.QualityLevel = 100; // "100" for maximum quality (largest file size).
encoder.Frames.Add(BitmapFrame.Create(image));
encoder.Save(stream);
小问题:由于原始问题是关于低质量的投诉,因此要解决使用最高质量问题:'encoder.QualityLevel = 100'。 – ToolmakerSteve 2017-08-05 11:14:51
社区维基答案,这是公认的,referrs从微软的例子。
然而,为了节省一些你的时候,我煮下来到一个本质和
IDisposable
。我还没有看到using (...) {
在任何其他答案。为了避免内存泄漏,最好的做法是处理实现IDisposable
的所有内容。public static void SaveJpeg(string path, Bitmap image)
{
SaveJpeg(path, image, 95L);
}
public static void SaveJpeg(string path, Bitmap image, long quality)
{
using (EncoderParameters encoderParameters = new EncoderParameters(1))
using (EncoderParameter encoderParameter = new EncoderParameter(Encoder.Quality, quality))
{
ImageCodecInfo codecInfo = ImageCodecInfo.GetImageDecoders().First(codec => codec.FormatID == ImageFormat.Jpeg.Guid);
encoderParameters.Param[0] = encoderParameter;
image.Save(path, codecInfo, encoderParameters);
}
}
小注:质量所示的“95L”是一个很好的默认值,因为它接近“100L”的最大值,但对于非常详细的图像,它会在文件大小上节省一些。我通常使用“90L”到“100L”来保存质量,“70L”到“85L”质量不错,但文件大小更合理。这也取决于你是否在对文件进行“重复编辑”。如果是这样,请使用“100L”直到上次编辑(或者在.png中编辑为无损),然后以您需要的任何质量进行最终保存。 – ToolmakerSteve 2017-08-05 12:05:45
工程。看起来没有这些,使用50L的标准质量。 – KdgDev 2009-09-28 00:39:06
你有一个错字。 jgpEncoder当你的意思是jpgEncoder;) – 2013-12-10 13:50:44
EncoderParameter可能会使用非托管资源,必须予以处置。 Msdn文档在这个问题上有点缺乏。它应该声明'Param'数组是用空元素初始化的(因此在第一次赋值给每个元素之前不需要处理),并且'EncoderParameters'将它的当前参数放置在自己的dispose中。 – 2014-07-11 10:34:57