Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中保存的JPG的质量#_C#_Image Processing - Fatal编程技术网

C# 在C中保存的JPG的质量#

C# 在C中保存的JPG的质量#,c#,image-processing,C#,Image Processing,我制作了一个小的C#应用程序来创建.jpg格式的图像 pictureBox.Image.Save(name,ImageFormat.Jpeg); 图像已成功创建。我输入一张原始图片,用它做一些事情并保存它。然而,这张新照片的质量比原来的低 有没有办法设置所需的质量?下面的代码示例演示如何使用EncoderParameter构造函数创建EncoderParameter。要运行此示例,请粘贴代码并调用varyqualityvel方法 此示例需要位于c:的名为TestPhoto.jpg的图像文件 p

我制作了一个小的C#应用程序来创建.jpg格式的图像

pictureBox.Image.Save(name,ImageFormat.Jpeg);
图像已成功创建。我输入一张原始图片,用它做一些事情并保存它。然而,这张新照片的质量比原来的低


有没有办法设置所需的质量?

下面的代码示例演示如何使用EncoderParameter构造函数创建EncoderParameter。要运行此示例,请粘贴代码并调用
varyqualityvel
方法

此示例需要位于c:的名为TestPhoto.jpg的图像文件

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;
}

参考:

查看MSDN在上的文章


您需要使用另一个Save()重载来获取ImageEncoder及其参数。

这是一个旧线程,但我已经重写了Microsoft(根据Dustin Getz的回答)以使其更有用—收缩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 );
    }
//
///检索给定MimeType的编码器信息
/// 
///字符串:Mimetype
///ImageCodecInfo:Mime info或null(如果未找到)
私有静态ImageCodeInfo GetEncoderInfo(字符串mimeType)
{
var encoders=ImageCodecInfo.GetImageEncoders();
返回编码器.FirstOrDefault(t=>t.MimeType==MimeType);
}
/// 
///使用给定的压缩将图像另存为JPeg
///注意:文件名后缀不会影响mime类型,mime类型为Jpeg。
/// 
///图像:要保存的图像
///字符串:将图像另存为的文件名。注意:后缀不会影响mime类型,它将是Jpeg。
///长:介于0和100之间的值。
私有静态void SaveJpegWithCompressionSetting(图像、字符串文件名、长压缩)
{
var eps=新编码器参数(1);
eps.Param[0]=新编码器参数(编码器.Quality,compression);
var ici=GetEncoderInfo(“图像/jpeg”);
保存(文件名、ici、eps);
}
/// 
///使用给定的压缩将图像另存为JPeg
///注意:文件名后缀不会影响mime类型,mime类型为Jpeg。
/// 
///图片:这张图片
///字符串:将图像另存为的文件名。注意:后缀不会影响mime类型,它将是Jpeg。
///长:介于0和100之间的值。
公共静态void SaveJpegWithCompression(此图像、字符串文件名、长压缩)
{
使用压缩设置保存JPEG(图像、文件名、压缩);
}

如果您使用的是.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);
确保质量为
,否则将出现
参数异常

使用无类型GDI+style()属性来设置JPEG质量看起来有些过分

一个直接的方法应该是这样的:

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);

参考:

社区维基的答案被接受,它引用了微软的一个例子

然而,为了节省你们中的一些时间,我把它归结为一个精髓

  • 用适当的方法包装
  • 已实现
    IDisposable
    。我没有在任何其他答案中看到
    使用(…){
    。为了避免内存泄漏,最好处理实现
    IDisposable
    的所有内容


这是可行的。如果没有所有这些,似乎使用了50L的标准质量。EncoderParameter可能使用非托管资源,并且必须进行处置。Msdn文档对此主题有点缺乏。它应该声明
Param
数组是用空元素初始化的(因此,在首次分配给每个元素之前,无需进行任何处理),
EncoderParameters
将其当前参数自行处理。这看起来不错,但是否有办法获得原始图像质量(50L或60L…)?然后我们可以将其设置回..@Jordan-这回答了一个与Rajendra提出的问题不同的问题。Rajendra询问是否有办法找出原始图像的质量设置,以便在输出时使用该质量。例如,如果文件最初为质量100,则以质量100保存。如果文件为质量50,则以质量50保存。这是一个旧的质量,并且多年来吸引了一些高质量的答案。我推荐or。直接进入我的代码库,非常感谢!另请参阅使用
的版本,以确保
处置
在结尾时立即发生。次要说明:由于最初的问题是关于低质量的投诉,因此要最大限度地解决该使用问题质量:
encoder.qualityvel=100
。次要说明:质量显示的“95L”是一个良好的默认值,因为它接近最大值“100L”,但对于非常详细的图像,将在文件大小上节省一点。我通常使用“90L”到“100L”来保持hiqh质量,“70L”到“85L”质量好,但文件大小更合理。这还取决于您是否对文件进行“重复编辑”。如果是这样,请使用“100L”直到最后一次编辑(或使用.png进行无损编辑),然后以所需的质量进行最终保存。
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);
    }
}