general.general : ImageMagick et conversion PNG
Posté par liberforce (Jabber id, page perso, ) le 08 avril 2008Bonjour,
Je tente de convertir une image bmp en png, afin d'obtenir un fichier le plus petit possible, mais dans un format sans pertes.
Mon image d'origine est en RGB, 24 bits par pixels, mais elle est en niveaux de gris (les valeurs de chacun des canaux sont identiques). Elle fait 320x240 pixels.
J'ai généré un premier png avec la commande:
convert original.bmp out.png
En regardant plus attentivement avec GIMP, j'ai vu que l'image de sortie était toujours en RGB, et pas en niveaux de gris. Après de longues (!) recherches sur les options de convert, j'ai trouvé la commande suivante:
convert original.bmp -type Grayscale out.png
Le png généré n'a plus qu'un seul canal en niveaux de gris, et ne pèse plus que 48 Ko, contre 64 Ko précédemment. J'ai néanmoins vu l'option -type Palette qui doit à priori utiliser des couleurs indexées. Et là, je descends à 20 Ko, nickel pour pour ce que je veux faire !
Sauf que... ça ne marche pas. En fait l'image est différente de l'original avec cette option, mais je ne sais pas pourquoi... Y a t'il un gourou qui pourrait m'expliquer comment avoir un fichier PNG le plus petit possible et identique à l'original ? Pourquoi j'ai une image différente en couleurs indexées ?
Merci.
> Lire le message (11 commentaires, moyenne: 2,1).
Vous avez demandé le commentaire #921582.



Chemins retords...
En transformant mon bmp en pgm (format brut en niveaux de gris), puis en convertissant cette dernière en png (avec l'option -type Palette pourtant), j'ai bien une image correcte, de 48 Ko.
J'ai donc l'impression que l'option Palette a dû essayer de transformer mon espace de couleurs RGB en palette indexée, sans passer par des niveaux de gris au milieu, ce qui a causé des pertes. Ces pertes ont eu pour effet de bord que le fichier se compresse mieux.
Mais impossible de descendre sous cette limite, sauf en utilisant l'outil pngcrush, qui peut faire descendre l'image à 40 Ko, mais c'est tout. J'avais testé convert avec l'option -quality 90, mais ça n'a pas changé grand chose... D'autres idées pour réduire la taille ?
[^]Palette
C'est bien l'option GrayScale qu'il faut que tu utilises. Tu ne gardes qu'un seul canal qui est la moyenne des canaux originaux.
Je crois que tu obtiens la même chose avec "-colorspace Gray". A tester.
Les options "-separate -channel Red" permettent aussi d'obtenir le même résultat en étant certain qu'il n'y a pas de modification (car de mémoire, GrayScale effectue une correction et pas simplement une moyenne. A vérifier).
Et pour finir: "-compress bzip" si le contenu de ton image le permet.
[^]Re: Palette
-colorspace Gray conserve bien la même image, mais conserve les 3 canaux RGB, contrairement à -type Grayscale qui ne conserve plus qu'un canal en niveaux de gris.
De plus Grayscale ne fait pas de correction, l'image est identique à celle de départ, chose confirmée par compare -metric AE original.bmp convert.png difference.png (et aussi par un petit soft de comparaison d'images que j'ai fait).
Pour la séparation de canaux, j'avais essayé, mais pas de différence avec Grayscale, ni en poids de l'image ni en taille.
L'option -compress n'a rien donné quelque soit la valeur utilisée, et -quality 100 me donne la même taille qu'initialement. Par conséquent, j'en déduis que j'ai un peu tout essayé. Tes indications m'ont montré que j'étais sur le bon chemin, merci :-)
[^]Re: Palette
J'utilise toujours "-quality 100" avec convert pour le PNG, ça permet d'obtenir la meilleure compression (qui est celle de la zlib et gzip, réglable elle entre 1 et 9), sinon le fichier est un peu plus gros (le défaut doit être le niveau 6 de la zlib).
Pour l'histoire de la palette, il est possible qu'une fois la conversion en niveaux de gris effectuée, si le nombre de nuances de gris présentes dans l'image est nettement inférieur à 256 (au pif genre 32), l'utilisation d'une palette permette de gagner un peu.
C'est clair que le BMP est à éviter, en plus ce n'est pas un standard du Web.
[^]Re: Palette
Certes, mais ce n'est absolument pas pour du web. Je fais de l'acquisition d'images sur 5 caméras numériques en même temps, et je voulais pouvoir conserver les images capturées sur disque.
L'ancien logiciel utilisait du jpeg, mais je préférais ne pas avoir de pertes. Le png met trop de temps à être généré (j'ai 125 images en 320x240 par secondes à enregistrer), donc j'ai choisi un format non compressé, pour faire la compression à postériori, sans risquer de diminuer les performances de la machine pendant l'acquisition. Bon, en fait ça n'a pas résolu le problème, car maintenant j'ai des problèmes de bande passante en écriture avec le disque dur (forcément, je stocke 24 bits par pixels alors que 8 suffiraient, et j'ai un disque 4200 tours/minute).
Le choix du bmp est aussi dû au fait que c'est le seul format non compressé que je peux enregistrer avec gdk-pixbuf dans GTK+. Le format pgm (sans compression, un seul canal en niveaux de gris) est lu, mais pas écrit :-( . Je vais d'ailleurs tenter de faire un patch pour ça, ça me servira au boulot, et ça pourrait être utile à d'autres...
http://bugzilla.gnome.org/show_bug.cgi?id=333278
[^]Re: Palette
Et le PNG non comprimé, ou alors comprimé avec le premier niveau de compression zlib (avec genre "-quality 0"), ça ne passe pas niveau CPU ?
Pour le format PGM il est super simple, un programme de 10 lignes peut le gérer.
[^]Bande passante disque
Il te faut peut-être utiliser un disque virtuel en mémoire. Si ta conversion se fait en continu, tes images brutes sont écrites sur le disque en mémoire, et les images finales sont sur un vrai disque.
[^]Re: Bande passante disque
On m'a déjà fait la remarque, mais comment tu fais quand quand l'enregistrement commence à saturer la RAM ? Le disque n'arrivera jamais à suivre...
Quand t'as un mec qui remplit une cuve avec un tuyau d'arrosage à pleine pression, et un autre qui essaie de la vider avec un verre, au bout d'un moment la cuve déborde...
[^]Re: Bande passante disque
Ca veut donc "juste" dire que ce que tu veux faire dépasse les capacités de ta machine. Donc c'est "juste" impossible :-)
Désolé ne n'avoir pu t'aider.
[^]Re: Bande passante disque
Ça ne sert à rien de mettre les images brutes en ramdisk, car tout fichier écrit sur disque l'est d'abord en mémoire, et il est "flushé" sur disque au bout de 5 secondes maximum. Dans le cas présent, une image brute ne sera présente qu'un bref instant sur disque avant d'être convertie et effacée, et en fait il n'y aura aucun trafic disque lié aux images brutes, elles ne quitteront pas le buffer cache.
[^]Re: Bande passante disque
Je tempère en disant que ça sert bien tout de même lorsque tes processus mettent plus de 2,5 secondes effacer les données.
Et la taille de mémoire occupée par le cache, autant l'utiliser pour un disque en mémoire. Tu es 100% certain que ça n'utilisera pas le disque. Ah... sauf en cas de swap. Je crois me souvenir d'une option quelque part à ce propos, pas sûr.
Je travaille sans swap depuis pas mal de temps, je ne sais plus comment faire pour éviter de jouer avec.