Compresión JPEG de alta calidad con c #

Estoy usando C # y quiero guardar imágenes usando el formato JPEG. Sin embargo, .NET reduce la calidad de las imágenes y las guarda con una compresión que no es suficiente.

Quiero guardar archivos con su calidad y tamaño originales. Estoy usando el siguiente código, pero la compresión y la calidad no son como las originales.

Bitmap bm = (Bitmap)Image.FromFile(FilePath); ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); ImageCodecInfo ici = null; foreach (ImageCodecInfo codec in codecs) { if (codec.MimeType == "image/jpeg") ici = codec; } EncoderParameters ep = new EncoderParameters(); ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100); bm.Save("C:\\quality" + x.ToString() + ".jpg", ici, ep); 

Estoy archivando fotos de estudio y la calidad y la compresión es muy importante. Gracias.

Parece que está configurando la calidad al 100%. Eso significa que no habrá compresión.

Si cambia el nivel de compresión (80, 50, etc.) y no está satisfecho con la calidad, es posible que desee probar una biblioteca de imágenes diferente. LEADTools tiene un buen motor (no gratuito).

ACTUALIZACIÓN: Como mencionó el comentarista, el 100% de calidad todavía no significa la compresión sin pérdida cuando se usa JPEG. Cargar la imagen, hacerle algo y luego guardarla de nuevo resultará en la degradación de la imagen. Si necesita modificar y guardar una imagen sin perder ninguno de los datos, necesita usar un formato sin pérdida como TIFF, PNG o BMP. Me gustaría ir con TIFF comprimido (ya que aún no tiene pérdidas aunque esté comprimido) o PNG.

El codificador .Net incorporado en la biblioteca (al menos la biblioteca predeterminada de Windows proporcionada por Microsoft) es bastante malo:

http://b9dev.blogspot.com/2013/06/nets-built-in-jpeg-encoder-convenient.html

Actualización parcial

Ahora estoy usando un enfoque que se describe aquí , que utiliza ImageMagick para el cambio de tamaño y luego jpegoptim para la compresión final, con mejores resultados. Me doy cuenta de que es una respuesta parcial, pero lo ampliaré una vez.

Respuesta anterior

ImageMagick es la mejor elección que he encontrado hasta ahora. Realiza una compresión jpeg relativamente sólida.

http://magick.codeplex.com/

Tiene un par de inconvenientes:

  1. Es mejor, pero no perfecto. En particular, su submuestreo Chroma está configurado con un alto nivel de detalle al 90% o más, luego salta a un nivel de detalle más bajo, que puede introducir muchos artefactos. Si quiere ignorar el submuestreo, esto es bastante conveniente. Pero si quisieras submuestrear en alto detalle a, por ejemplo, 50%, tienes un gran desafío por delante. Tampoco alcanzará los niveles de calidad / compresión de Photoshop o Google PageSpeed.

  2. Tiene una carga de implementación especial en el servidor que es muy fácil de perder. Requiere una versión de Visual Studio 2008 SDK lib instalada. Esta lib está disponible en cualquier máquina de desarrollo con Visual Studio en ella, pero luego accedes al servidor por primera vez e implosiona con un error oscuro. Es uno de esos problemas que la mayoría de la gente no tendrá encriptados / automatizados, y se tropezará con él durante una futura migración del servidor.

La respuesta más antigua

Busqué y encontré un proyecto para implementar un codificador JPEG C # traduciendo un proyecto C sobre:

http://www.codeproject.com/Articles/83225/A-Simple-JPEG-Encoder-in-C

que simplifiqué un poco:

https://github.com/b9chris/ArpanJpegEncoder

Produce archivos JPEG de mayor calidad que el .Net incorporado, pero aún no es tan bueno como el de Gimp o Photoshop. Los tamaños de archivos también tienden a ser más grandes.

La implementación de BitMiracle es prácticamente idéntica a la .Net incorporada: los mismos problemas de calidad.

Es probable que la opción más eficiente sea empaquetar una implementación de código abierto existente, como el jpeg_optimizer de Google en PageSpeed ​​Tools , aparentemente libjpeg debajo.

Actualizar

Parece que ArpanJpegEncoder tiene problemas una vez que se implementó, tal vez necesito boost el nivel de confianza del código, o tal vez esté sucediendo algo más. Localmente escribe bien las imágenes, pero una vez desplegado, obtengo una imagen negra en blanco cada vez. Actualizaré si determino la causa. Solo una advertencia para que otros lo consideren.

La compresión y la calidad son siempre una compensación.

Los archivos JPEG siempre tendrán pérdidas.

Es posible que desee considerar el uso de PNG y minificar los archivos con PNGCrush o PNGauntlet.

En cuanto a la configuración del nivel de compresión en .NET, consulte este enlace (todo incluido): http://msdn.microsoft.com/en-us/library/bb882583.aspx

En cuanto a su pregunta: generalmente guardará la imagen cargada de los usuarios como PNG, luego usará este PNG como base para generar sus JPG con diferentes tamaños (¡y colocará una marca de agua SOLAMENTE en los JPG, nunca en el PNG original!). esto es: si cambia las dimensiones de las imágenes más tarde para su plataforma, tiene el archivo PNG original guardado y, en base a esto, puede volver a computar cualquier tamaño de imagen nuevo.

Debe guardar el archivo como su calidad y tamaño original

Eso no tiene mucho sentido. Cuando usa compresión con pérdida, perderá información por definición. El objective de comprimir una imagen es reducir el tamaño del archivo. Si necesita alta calidad y jpeg no lo hace por usted, es posible que tenga que utilizar algún tipo de compresión sin pérdida, pero los tamaños de sus archivos no se reducirán demasiado. Siempre puedes intentar usar la biblioteca “estándar” para comprimir a jpeg ( libjpeg) y ver si eso te da resultados diferentes (lo dudo, pero no sé qué usa .NET bajo el capó).

La compresión del formato jpeg por su propia naturaleza reduce la calidad. Tal vez debería considerar la compresión de archivos, como #ziplib . Es posible que pueda obtener una compresión razonable sobre un grupo de archivos.