una - Calidad de un JPG guardado en C#
redimensionar imagen vb net (7)
Hice una pequeña aplicación de C # para crear una imagen en formato .jpg.
pictureBox.Image.Save(name,ImageFormat.Jpeg);
La imagen fue creada con éxito. Ingresé una foto original, hago algunas cosas con ella y la guardo. La calidad de esta nueva imagen, sin embargo, es inferior a la del original.
¿Hay alguna manera de establecer la calidad deseada?
Aquí hay un fragmento de código aún más compacto para guardar como JPEG con una calidad específica:
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);
O bien, si las líneas anchas de 120 caracteres son demasiado largas para ti:
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);
¡Asegúrate de que la calidad sea long
o obtendrás una ArgumentException
!
Consulte el artículo de MSDN sobre cómo configurar el nivel de compresión JPEG .
Necesita usar la otra sobrecarga Save () que toma un ImageEncoder y sus parámetros.
El siguiente ejemplo de código muestra cómo crear un parámetro Codificador utilizando el constructor Parámetro Encoder. Para ejecutar este ejemplo, pegue el código y llame al método VaryQualityLevel
.
Este ejemplo requiere un archivo de imagen llamado TestPhoto.jpg ubicado en 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;
}
Ref: http://msdn.microsoft.com/en-us/library/system.drawing.imaging.encoderparameter.aspx
El uso de atributos de estilo sin formato GDI + ( https://msdn.microsoft.com/en-us/library/windows/desktop/ms533845(v=vs.85).aspx ) para configurar la calidad JPEG parece excesivo.
Una forma directa debería verse así:
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);
Este es un hilo viejo, pero he reescrito Microsoft (según la respuesta de Dustin Getz) para que sea un poco más útil, reduciendo GetEncoderInfo y haciendo una extensión en Image. De todos modos, nada realmente nuevo, pero puede ser útil:
/// <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 );
}
La respuesta wiki de la comunidad, que es aceptada, se refiere a un ejemplo de Microsoft.
Sin embargo, para ahorrar algo de tu tiempo, lo reduje a una esencia y
- Lo empaqueté en un método apropiado
- Implementado
IDisposable
. No he vistousing (...) {
en ninguna otra respuesta. Para evitar fugas de memoria, lo mejor es eliminar todo lo que implementeIDisposable
.
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);
}
}
Si está utilizando .NET Compact Framework, una alternativa podría ser utilizar el formato sin pérdida PNG, es decir:
image.Save(filename, ImageFormat.Png);