web-dev-qa-db-fra.com

Je veux changer le DPI avec ImageMagick sans changer la taille en octets réelle des données d'image

Dans GIMP, il existe un moyen très simple de faire ce que je veux. Je n'ai que la boîte de dialogue allemande installée, mais je vais essayer de la traduire. Je parle d’aller à Picture -> PrintingSize et d’ajuster ensuite les valeurs X-Resolution et Y-Resolution qui m’appellent des valeurs dites DPI. Vous pouvez également choisir le format qui par défaut est Pixel/Inch. (En allemand, le dialogue est Bild -> Druckgröße et il y a X-Auflösung et Y-Auflösung)

Ok, les valeurs ici sont souvent 72 par défaut. Lorsque je les change, par exemple 300 ceci a pour effet que l'image reste la même sur l'ordinateur, mais si je l'imprime, elle sera plus petite si vous la regardez, mais tous les détails sont toujours là, mais plus petits -> la résolution est plus élevée papier imprimé (mais de plus petite taille ... ce qui me convient).

Je le fais souvent lorsque je travaille avec LaTeX, ou pour être exact avec la commande pdflatex sur une machine Ubuntu récente. Lorsque je fais manuellement le processus ci-dessus avec GIMP, tout fonctionne correctement. Les images apparaîtront plus petites dans le résultat PDF, mais avec une qualité d'impression élevée.

Ce que j'essaie de faire est d'automatiser le processus de saisie dans GIMP et d'ajuster les valeurs DPI. Comme ImageMagick est réputé pour être superbe et que je l’ai utilisé pour de nombreuses autres tâches, j’ai essayé d’atteindre mon objectif avec cet outil. Mais ça ne fait tout simplement pas ce que je veux.

Après avoir essayé beaucoup de choses, je pense que c'est en fait la commande qui devrait être mon ami:

convert input.png -density 300 output.png

Cela devrait régler le DPI à 300, comme je peux le lire partout sur le Web. Cela semble fonctionner. Mais lorsque je vérifie le fichier, il reste le même (EDIT: ce que j’attends, comme expliqué ci-dessus).

file input.png output.png
     input.png: PNG image data, 611 x 453, 8-bit grayscale, non-interlaced
    output.png: PNG image data, 611 x 453, 8-bit grayscale, non-interlaced

Quand j'utilise cette commande, il me semble que c'est ce que j'ai voulu:

identify -verbose output.png | grep 300
    Resolution: 300x300
    PNG:pHYs                 : x_res=300, y_res=300, units=0

Assez drôle, la même sortie est fournie pour input.png, ce qui me déroute ... alors ce pourrait être les mauvais paramètres à surveiller?

Mais lorsque je rends maintenant mon TeX avec pdflatex, l'image est toujours grande et floue. De plus, lorsque j'ouvre à nouveau l'image avec GIMP, les valeurs DPI sont définies sur 72 au lieu de 300. Donc, il n'y a pas eu d'effet du tout.

Maintenant, quel est le problème ici. Est-ce que je me trompe complètement? Je ne peux pas me tromper car tout fonctionne parfaitement avec GIMP.

Merci pour toute aide dans ce domaine. Je suis également ouvert à d'autres solutions automatisées faciles à mettre en œuvre sur un système Linux.

44
Boris Däppen

Spécifiez les unités - je semble me rappeler avoir eu un problème lorsque j'ai omis cette option (bien que DPI devrait être la valeur par défaut), par exemple:

convert -units PixelsPerInch input.png -density 300 output.png

Savez-vous quels champs de données intégrées GIMP utilise pour lire la résolution - a-t-il ses propres champs qui remplacent les champs standard utilisés par ImageMagick? Par exemple, Photoshop utilise Photoshop:XResolution et Photoshop:YResolution. Vous devez donc les configurer pour qu’il reconnaisse un paramètre de densité (ImageMagick ne peut pas le faire - nous utilisons ExifTool).

74
Martin Wilson

Notez que vous pouvez utiliser Exiftool pour lire les résolutions. Par exemple, Exiftool '-*resolution*' c.jpg pourrait indiquer

Unité de résolution: pouces X résolution: 300 Y résolution: 300

Exiftool peut également définir des paramètres, mais comme indiqué dans la page de manuel Image::ExifTool::TagNames, les balises supplémentaires XResolution et YResolution ne sont pas inscriptibles dans Exiftool.

Je ne sais pas si ImageMagick a des options de changement de résolution, mais je serais surpris de ne pas le faire. En outre, il est simple d'écrire des scripts GIMP pour automatiser de telles tâches, et il est également possible de changer les résolutions avec de petits programmes. Par exemple, voici un programme C (compilable via gcc setRes.c -O3 -Wall -o setRes) qui lit les premiers octets d’un fichier jpeg, modifie la résolution en 300 et les réécrit. Le programme illustré utilise des constantes pour les machines little-endian, telles que x86. S'il est exécuté sur une machine big-endian, il devrait se terminer par un message tel que Error: xyz may be not a .jpg file, même si xyz est un fichier jpeg. Notez que je n'ai pas testé les images obtenues via pdflatex; vous trouverez probablement intéressant de poster une question dans le tex SE .

/* jiw -- 24 Sep 2012 -- Re: set resolution in a jpg -- Offered without
warranty under GPL v3 terms as at http://www.gnu.org/licenses/gpl.html
*/
#include <stdlib.h>
#include <stdio.h>
void errorExit(char *msg, char *par, int fe) {
  fprintf (stderr, "\n%3d Error: %s %s\n", fe, msg, par);
  exit (1);
}
// Note, hex constants are byte-reversed on little vs big endian machines
enum { JF=0x464a, IF=0x4649, L300=0x2c01, B300=0x012c, NEWRES=L300};
int main(int argc, char *argv[]) {
  FILE *fi;
  short int buf[9];
  int r, L=sizeof buf;
  if (argc<2) errorExit(argv[0], "requires a .jpg file name", 0);
  fi = fopen(argv[1], "r+b");
  if(!fi) errorExit("open failed for", argv[1], ferror(fi));
  r = fread(buf, 1, L, fi);
  if (r != L) errorExit("read failed for", argv[1], ferror(fi));
  if (buf[3] != JF || buf[4] != IF) // Check JFIF signature
    errorExit(argv[1], "may be not a .jpg file", 0);
  buf[7] = buf[8] = NEWRES;
  fseek(fi, 0, SEEK_SET);
  r = fwrite(buf, 1, L, fi);
  if (r != L) errorExit("write failed for", argv[1], ferror(fi));
  return 0;
}
5

Je ne pouvais pas comprendre comment convaincre convertir d'ajouter uniquement les métadonnées et de ne pas recoder le bitmap [monochrome]; il élargissait le fichier> 50%.

J'ai découvert que pngcrush (pas un outil ImageMagick) peut également ajouter des métadonnées de densité. Cette ligne de commande le marque à 600 dpi et permet d'autres optimisations, ce qui réduit la taille du fichier d'environ 10%:

pngcrush -res 600 in.png out.png
2
Charles Boling