web-dev-qa-db-fra.com

Compression JPEG de haute qualité avec c #

J'utilise C # et je souhaite enregistrer des images au format JPEG. Cependant .NET réduit la qualité des images et les enregistre avec une compression qui n'est pas suffisante.

Je souhaite enregistrer des fichiers avec leur qualité et leur taille d'origine. J'utilise le code suivant mais la compression et la qualité ne sont pas comme celles d'origine.

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

J'archive des photos de studio et la qualité et la compression sont très importantes. Merci.

35
Baran

Il semble que vous définissiez la qualité à 100%. Cela signifie qu'il n'y aura pas de compression.

Si vous changez le niveau de compression (80, 50, etc.) et que vous n'êtes pas satisfait de la qualité, vous voudrez peut-être essayer une bibliothèque d'images différente. LEADTools a un bon moteur (non libre).

MISE À JOUR: Comme un commentateur l'a mentionné, une qualité à 100% ne signifie toujours pas une compression sans perte lors de l'utilisation de JPEG. Charger l'image, y faire quelque chose, puis la réenregistrer entraînera finalement une dégradation de l'image. Si vous devez modifier et enregistrer une image sans perdre aucune des données, vous devez utiliser un format sans perte tel que TIFF, PNG ou BMP. J'irais avec TIFF compressé (car il est toujours sans perte même s'il est compressé) ou PNG.

11
Michael Todd

L'encodeur .Net intégré à la bibliothèque (au moins la bibliothèque Windows par défaut fournie par Microsoft) est assez mauvais:

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

Mise à jour partielle

J'utilise maintenant ne approche décrite ici , qui utilise ImageMagick pour le redimensionnement puis jpegoptim pour la compression finale, avec de bien meilleurs résultats. Je me rends compte que c'est une réponse partielle, mais je développerai cela une fois que le temps le permettra.

Réponse plus ancienne

ImageMagick est le meilleur choix que j'ai trouvé jusqu'à présent. Il effectue une compression JPEG relativement solide.

http://magick.codeplex.com/

Il a quelques inconvénients:

  1. C'est mieux mais pas parfait. En particulier, son sous-échantillonnage Chroma est défini sur des détails élevés à 90% ou plus, puis passe à un niveau de détail inférieur - celui qui peut introduire de nombreux artefacts. Si vous voulez ignorer le sous-échantillonnage, c'est en fait assez pratique. Mais si vous vouliez un sous-échantillonnage très détaillé, par exemple 50%, vous avez un plus grand défi à relever. Il n'atteindra pas non plus tout à fait les niveaux de qualité/compression de Photoshop ou de Google PageSpeed.

  2. Il a un fardeau de déploiement spécial sur le serveur qui est très facile à manquer. Il nécessite une bibliothèque SDK Visual Studio 2008 installée. Cette bibliothèque est disponible sur n'importe quelle machine de développement avec Visual Studio dessus, mais vous frappez le serveur pour la première fois et elle implose avec une erreur obscure. C'est l'un de ces pièges cachés que la plupart des gens n'auront pas scriptés/automatisés, et vous les trébucherez lors d'une future migration de serveur.

Réponse la plus ancienne

J'ai fouillé et j'ai trouvé un projet pour implémenter un encodeur C # JPEG en traduisant un projet C sur:

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

que j'ai légèrement simplifié:

https://github.com/b9chris/ArpanJpegEncoder

Il produit des fichiers JPEG de bien meilleure qualité que le .Net intégré, mais n'est toujours pas aussi bon que Gimp ou Photoshop. Les tailles de fichiers ont également tendance à être plus grandes.

implémentation de BitMiracle est pratiquement identique au .Net intégré - mêmes problèmes de qualité.

Il est probable que simplement envelopper une implémentation open source existante, comme jpeg_optimizer de Google dans PageSpeed ​​Tools - apparemment libjpeg en dessous, serait l'option la plus efficace.

Mise à jour

ArpanJpegEncoder semble avoir des problèmes une fois qu'il est déployé - peut-être que je dois augmenter le niveau de confiance du code, ou peut-être que quelque chose d'autre se passe. Localement, il écrit très bien les images, mais une fois déployé, j'obtiens une image noire vierge à chaque fois. Je mettrai à jour si je détermine la cause. Juste un avertissement à ceux qui le considèrent.

19
Chris Moschini

La compression et la qualité sont toujours un compromis.

Les fichiers JPEG seront toujours avec perte.

Vous pouvez envisager d'utiliser PNG et de réduire les fichiers à l'aide de PNGCrush ou PNGauntlet

6
John Gietzen

Concernant la configuration du niveau de compression dans .NET, veuillez vérifier ce lien (tout inclus): http://msdn.Microsoft.com/en-us/library/bb882583.aspx

Redéfinir votre question: Habituellement, vous enregistrez l'image téléchargée des utilisateurs au format PNG, puis vous utilisez ce PNG comme base pour générer vos JPG de différentes tailles (et vous mettez un filigrane UNIQUEMENT sur les JPG, jamais sur le PNG d'origine!) ceci est: si vous modifiez vos dimensions d'images plus tard pour votre plate-forme, vous avez enregistré le PNG d'origine et basé sur cela, vous pouvez recalculer toutes les nouvelles tailles d'image.

2
johngrinder

Il doit enregistrer le fichier comme sa qualité et sa taille d'origine

Cela n'a pas beaucoup de sens. Lorsque vous utilisez la compression avec perte, vous allez perdre des informations par définition. Le point de compression d'une image est de réduire la taille du fichier. Si vous avez besoin de haute qualité et que jpeg ne le fait pas pour vous, vous devrez peut-être opter pour un type de compression sans perte, mais la taille de vos fichiers ne sera pas réduite de beaucoup. Vous pouvez toujours essayer d'utiliser la bibliothèque "standard" pour compresser en jpeg ( libjpeg) et voir si cela vous donne des résultats différents (j'en doute, mais je ne sais pas ce que .NET utilise sous la hotte.)

0
Ed S.

La compression du format jpeg par sa nature même réduit la qualité. Vous devriez peut-être vous pencher sur la compression de fichiers, comme # ziplib . Vous pourrez peut-être obtenir une compression raisonnable sur un groupe de fichiers.

0
C. Ross