2008-09-03 17 views
48

¿Hay alguna forma de convertir una imagen bmp a jpg/png sin perder la calidad en C#? Usando la clase de imagen podemos convertir bmp a jpg pero la calidad de la imagen de salida es muy pobre. ¿Podemos obtener el nivel de calidad tan bueno como una imagen convertida a jpg usando photoshop con la más alta calidad?Bmp a jpg/png en C#

Respuesta

53
var qualityEncoder = Encoder.Quality; 
var quality = (long)<desired quality>; 
var ratio = new EncoderParameter(qualityEncoder, quality); 
var codecParams = new EncoderParameters(1); 
codecParams.Param[0] = ratio; 
var jpegCodecInfo = <one of the codec infos from ImageCodecInfo.GetImageEncoders() with mime type = "image/jpeg">; 
bmp.Save(fileName, jpegCodecInfo, codecParams); // Save to JPG 
+1

¿No debería haber algunas declaraciones _using_ aquí? Noto que EncoderParameter es IDisposable, pero no soy lo suficientemente experto en el patrón desechable para decir con certeza que son necesarios. – TwainJ

3

This parece que tiene algo de código fuente que pueda ayudar ... sospecho que se acaba perdiendo el parámetro de calidad codificador < encogimiento>

0

Usted puede tratar de:

Bitmap.InterpolationMode = InterpolationMode.HighQualityBicubic; 

y

Bitmap.CompositingQuality = CompositingQuality.HighQuality; 

Lo que mantiene la calidad bastante alta, pero no el más alto posible le.

+0

Bitmap no tiene tales propiedades. Deben aplicarse a los gráficos y durante las modificaciones de la imagen, como el cambio de tamaño. –

1

Fundamentalmente no podrá mantener la misma calidad porque jpg es (por lo que yo sé) siempre con pérdida, incluso con la configuración de calidad más alta posible.

Si la calidad de precisión es realmente importante, considere usar png, que tiene algunos modos sin pérdida.

1

Solo quiero decir que JPEG es por naturaleza un formato con pérdida. Entonces, incluso en las configuraciones más altas, perderás algo de información, pero depende mucho de la imagen. Pero png no tiene pérdidas.

30
public static class BitmapExtensions 
{ 
    public static void SaveJPG100(this Bitmap bmp, string filename) 
    {    
     EncoderParameters encoderParameters = new EncoderParameters(1); 
     encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L); 
     bmp.Save(filename, GetEncoder(ImageFormat.Jpeg), encoderParameters); 
    } 

    public static void SaveJPG100(this Bitmap bmp, Stream stream) 
    { 
     EncoderParameters encoderParameters = new EncoderParameters(1); 
     encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L); 
     bmp.Save(stream, GetEncoder(ImageFormat.Jpeg), encoderParameters); 
    } 

    public static ImageCodecInfo GetEncoder(ImageFormat format) 
    { 
     ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders(); 

     foreach (ImageCodecInfo codec in codecs) 
     { 
      if (codec.FormatID == format.Guid) 
      { 
       return codec; 
      } 
     } 

     return null; 
    } 
} 
+0

expresión equivalente para getEncoder en una línea:. '' 'ImageCodecInfo.GetImageDecoders volver() donde (x => x.FormatID == format.Guid) .FirstOrDefault();' '' – Nuzzolilo

+2

O incluso más corto 'retorno ImageCodecInfo.GetImageEncoders(). FirstOrDefault (x => x.FormatID == ImageFormat.Jpeg.Guid); '. – Jan

10

Siempre BitmapExtensions by jestro es bueno, yo los usé. Sin embargo le gustaría mostrar la versión corregida - que funciona para la clase padre imagen que es más conveniente, ya que pienso y proporciona una manera de suministrar la calidad:

public static class ImageExtensions 
{ 
    public static void SaveJpeg(this Image img, string filePath, long quality) 
    { 
     var encoderParameters = new EncoderParameters(1); 
     encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, quality); 
     img.Save(filePath, GetEncoder(ImageFormat.Jpeg), encoderParameters); 
    } 

    public static void SaveJpeg(this Image img, Stream stream, long quality) 
    { 
     var encoderParameters = new EncoderParameters(1); 
     encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, quality); 
     img.Save(stream, GetEncoder(ImageFormat.Jpeg), encoderParameters); 
    } 

    static ImageCodecInfo GetEncoder(ImageFormat format) 
    { 
     ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders(); 
     return codecs.Single(codec => codec.FormatID == format.Guid); 
    } 
} 
0

Estoy trabajando en una aplicación de informe de gastos, y estoy realmente satisfecho con la configuración de calidad predeterminada para JPG (y PNG) al guardar desde un objeto Bitmap.

https://msdn.microsoft.com/en-us/library/9t4syfhh%28v=vs.110%29.aspx

Bitmap finalBitmap = ....; //from disk or whatever 
finalBitmap.Save(xpsFileName + ".final.jpg", ImageFormat.Jpeg); 
finalBitmap.Save(xpsFileName + ".final.png", ImageFormat.Png); 

Estoy en .NET 4.6 ... tal vez la calidad ha mejorado en versiones posteriores del marco.

Cuestiones relacionadas