Me sorprendió mucho cuando cargué un archivo jpg y lo cambié con una calidad de 100 y el tamaño era casi 4 veces el original. Para seguir investigando, abrí y guardé sin establecer explícitamente la calidad y el tamaño del archivo era exactamente el mismo. Pensé que esto era porque nada había cambiado, así que solo estaba escribiendo los mismos bits en un archivo. Para probar esta suposición, dibujé una línea grande y gruesa en diagonal sobre la imagen y guardé nuevamente sin establecer la calidad (esta vez esperaba que el archivo saltara porque sería "sucio") pero disminuyó ~ 10Kb.¿Qué nivel de calidad utiliza Image.Save() para archivos jpeg?
En este momento, realmente no entiendo lo que sucede cuando simplemente llamo a Image.Save() sin especificar una calidad de compresión. ¿Cómo está tan cerca el tamaño del archivo (después de que se modificó la imagen) al tamaño original cuando aún no se establece la calidad cuando configuro la calidad a 100 (básicamente sin compresión) el tamaño del archivo es varias veces mayor que el original?
He leído la documentación sobre Image.Save() y no tengo ningún detalle sobre lo que está sucediendo detrás de las escenas. He buscado en Google de todas las formas en que puedo pensar, pero no puedo encontrar ninguna información adicional que explique lo que estoy viendo. He estado trabajando durante 31 horas seguidas, así que tal vez me falta algo obvio; 0)
Todo esto ha sucedido mientras implemento algunos métodos de biblioteca para guardar imágenes en una base de datos. Sobrecargué nuestro método "SaveImage" para permitir establecer explícitamente una calidad y durante mi prueba me encontré con los resultados impares (para mí) explicados anteriormente. Cualquier luz que puedas arrojar será apreciada.
Aquí hay un código que va a ilustrar lo que estoy experimentando:
string filename = @"C:\temp\image testing\hh.jpg";
string destPath = @"C:\temp\image testing\";
using(Image image = Image.FromFile(filename))
{
ImageCodecInfo codecInfo = ImageUtils.GetEncoderInfo(ImageFormat.Jpeg);
// Set the quality
EncoderParameters parameters = new EncoderParameters(1);
// Quality: 10
parameters.Param[0] = new EncoderParameter(
System.Drawing.Imaging.Encoder.Quality, 10L);
image.Save(destPath + "10.jpg", codecInfo, parameters);
// Quality: 75
parameters.Param[0] = new EncoderParameter(
System.Drawing.Imaging.Encoder.Quality, 75L);
image.Save(destPath + "75.jpg", codecInfo, parameters);
// Quality: 100
parameters.Param[0] = new EncoderParameter(
System.Drawing.Imaging.Encoder.Quality, 100L);
image.Save(destPath + "100.jpg", codecInfo, parameters);
// default
image.Save(destPath + "default.jpg", ImageFormat.Jpeg);
// Big line across image
using (Graphics g = Graphics.FromImage(image))
{
using(Pen pen = new Pen(Color.Red, 50F))
{
g.DrawLine(pen, 0, 0, image.Width, image.Height);
}
}
image.Save(destPath + "big red line.jpg", ImageFormat.Jpeg);
}
public static ImageCodecInfo GetEncoderInfo(ImageFormat format)
{
return ImageCodecInfo.GetImageEncoders().ToList().Find(delegate(ImageCodecInfo codec)
{
return codec.FormatID == format.Guid;
});
}
Hice algunos experimentos sobre las compresiones para JPG en .NET y los errores correspondientes, véase http://www.c4real.biz/jpgCompression.aspx. –
Según algunas pruebas rápidas, parece que su intuición original es correcta: si tiene una Imagen que originalmente era jpg y llama a Guardar sin especificar la calidad, simplemente vaciará los bits originales en el archivo. Si ha modificado la imagen en la memoria, o si solicita un nivel de compresión particular, volverá a codificar la imagen. Si solicita un nivel de alta calidad para una imagen que proviene de una fuente de baja calidad, está desperdiciando mucho espacio tratando de describir con mucha precisión todos los artefactos introducidos por la compresión original. – sethobrien