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

45

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 -> PrintingSizeet ensuite d'ajuster les valeurs X-Resolutionet Y-Resolutionque je connais comme les valeurs dites DPI. Vous pouvez également choisir le format qui est par défaut Pixel/Inch. (En allemand le dialogue est Bild -> Druckgrößeet là X-Auflösunget Y-Auflösung)

Ok, les valeurs y sont souvent 72par défaut. Lorsque je les change en exemple, 300cela 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à, juste un peu plus petits -> ça a une résolution plus élevée sur le 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 pdflatexd'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 PDF résultant, mais avec une qualité d'impression élevée.

Ce que je cherche à faire est d’automatiser le processus d’ouverture de 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 vient pour input.pngce qui me trouble ... alors ce pourrait être les mauvais paramètres à surveiller?

Mais quand je rends maintenant mon TeX avec pdflatexl’image, elle est toujours grosse et floue. De plus, lorsque j'ouvre à nouveau l'image avec GIMP, les valeurs DPI sont définies sur au 72lieu 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.

Boris Däppen
la source
user1694803: N'oubliez pas de revenir à la réponse de Martin Wilson et de la «revigorer» (cliquez sur la petite ^icône à gauche de sa réponse), pas seulement «l'accepter» dès que vous avez assez de réputation personnelle (je pense que vous avez besoin +15) ...
Kurt Pfeifle le

Réponses:

76

Spécifiez les unités - je semble me souvenir 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:XResolutionet Photoshop:YResolutionvous devez donc les configurer pour qu'il reconnaisse un paramètre de densité (ImageMagick ne peut pas le faire - nous utilisons ExifTool).

Martin Wilson
la source
2
Je devais mettre -density 300avant input.png. Je convertissais des PDF. Merci quand même.
akostadinov
Pour la conversion PNG en TIFF que j’avais besoin d’utiliser -set units PixelsPerInch -density 300, simple -unitsne fonctionnait pas, quel que soit l’ordre des options.
Andrey
5

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

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

Exiftool est également capable de 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 en 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. Si elle est exécutée sur une machine big-endian, elle devrait se terminer par un message comme Error: xyz may be not a .jpg file, même si xyz est un fichier jpeg. Remarque, je n'ai pas testé les images résultantes via pdflatex; vous trouverez probablement utile de poser 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;
}
James Waldby - jwpat7
la source
1
Cela ne m'aide pas beaucoup, car je traite avec la PNG et n'ai pas la moindre idée de JPG ou même de C. C'est trop pour que la connaissance soit "profonde". Peut-être que quelqu'un d'autre peut l'utiliser.
Boris Däppen
Oui, j'aurais dû faire plus attention à la question! En le relisant, JPG n'est pas mentionné, PNG l'est clairement.
James Waldby - jwpat7
Oui, je suis quelqu'un d'autre et je peux l' utiliser: j'ai ouvert mon fichier .jpg dans un éditeur hexadécimal et modifié les neuvième et onzième octets pour la densité verticale et horizontale. Pour ainsi dire, j'ai "exécuté" votre code manuellement.
u_Ltd.
2

Je ne pouvais pas comprendre comment convaincre convertir pour ajouter uniquement les métadonnées et ne pas ré-encoder mon bitmap [monochrome]; il s'agissait d'élargir le fichier> 50%.

J'ai découvert que pngcrush (et non un outil ImageMagick) peut également ajouter les 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
Charles Boling
la source
-1

"Je souhaite modifier le DPI avec Imagemagick sans changer la taille en octets réelle des données d'image."

C'est complètement impossible!

Car:

     more "Dots per Inch" 
<==> more pixels per area 
<==> more total pixels per image 
<==> more total bytes per image

En outre, vous ne semblez pas comprendre ce qu'est le DPI en réalité:

  1. C'est une valeur totalement abstraite qui n'a de valeur pratique que si vous connaissez également la taille absolue de l'impression ou du rendu à l'écran ou sur le moniteur:
    • Vous pouvez "imprimer" la même image de 72x72 pixels sur un carré large d'un pouce: la résolution de l'impression sera de 72dpi.
    • Vous pouvez également l’imprimer sur un carré large de 1/4 de pouce: l’impression aura alors une résolution de 288dpi.
    • ( Remarque: si vous l’imprimez 288dpisur un carré de 1 pouce, ce n’est plus la même image: elle aura subi une extrapolation à travers le pilote de l’imprimante ou un autre mécanisme de filtrage, et sera devenue une image de 288x288 pixels au lieu de une image de 72x72 pixels ... )
  2. Les deux impressions auront exactement les mêmes informations d'image: l'image de 288 dpi n'aura pas soudainement plus d'informations.

Si vous souhaitez imprimer l'image d'origine de 72 x 72 pixels sous la forme d'un carré large d'un pouce, mais au lieu de 288dpi, vous devrez redimensionner l'image (dans ce cas, en la redimensionnant). Pour chaque pixel de l'original, vous aurez besoin de 4 pixels de la nouvelle image redimensionnée. Maintenant, il existe différents algorithmes qui peuvent être utilisés pour calculer les valeurs de couleur que ces 4 pixels (dont 3 nouveaux pixels) doivent avoir:

  • vous pouvez leur donner le même que le pixel d'origine (qui est un algorithme très "brut",
  • ou vous pouvez faire une moyenne de la valeur de couleur du pixel d'origine avec les valeurs de couleur des pixels voisins.

Dans tous les cas, vous créez une image plus grande composée de 288 lignes de pixels de 288 pixels de haut (288x288 pixels).

Ce que Gimp fait pour vous lorsque vous passez par "Image -> Taille d'impression": cela simplifie le processus de calcul à nouveau des modifications requises dans les tailles de pixels absolues, ce qui le rend plus convivial. Dans ce but...

  • ... il vous pose d’abord des questions sur le DPI car une imprimante donnée ne peut pas modifier sa résolution d’impression de manière arbitraire (certaines peuvent offrir non pas une, mais peut-être même 2 ou 3 résolutions différentes). Donc, il vous demande à quelle résolution vous souhaitez imprimer. C'est la première information.
  • ... alors il demande également la deuxième pièce de l' info: au cours de laquelle la taille (en cm, mmou inch) l'impression doit apparaître sur le papier.

En fonction de ces deux informations, Gimp calcule ensuite le nombre total de pixels qu’il doit utiliser (extrapoler à partir du nombre de pixels initial) pour remplir l’espace demandé à la résolution demandée.

Cependant, le fait de redimensionner une image raster en lui faisant contenir plus de pixels n’ajoute pas de véritables informations, mais ajoute simplement une "qualité" fictive. Cela peut sembler plus agréable à l'œil humain si votre algorithme de mise à l'échelle est «bon». Et cela aura l'air moche, si vous doublez, tripler ou quadrupler les pixels existants, comme le font certains algorithmes simples.

Pour les images raster,
le paramètre PPP n'est pertinent que dans le contexte de son impression ou de son affichage . Parce que les imprimantes ou les moniteurs ont donné des résolutions fixes. Par conséquent, c'est l'info que ...

  • ... un pilote d'imprimante ou
  • ... une application de traitement d'images prenant en charge l'impression

dois savoir.

Et la documentation d'ImageMagick est tout à fait en accord avec moi:

-density width
-density widthxheight
Définissez la résolution horizontale et verticale d'une image pour le rendu sur les périphériques.

Pour les images vectorielles ou les formats de fichier
(tels que PDF ou PostScript), le paramètre DPI est toutefois extrêmement important dans le contexte deleur tramage . Une résolution plus élevée transférera plus d'informations d'image dans le format de trame et préservera ainsi plus de détails de la qualité d'origine réelle. Lors de la conversion d'une image vectorielle d'une taille donnéemm,cmouinchen raster avec une résolution plus élevée, se traduira directement par un nombre plus élevé de pixels au total dans l'image.

En outre, ImageMagick ne prend pas en charge l'impression en tant que telle. Au lieu de cela, ImageMagick uniquement ...

  • ... convertit les fichiers d'un format raster donné vers d'autres formats raster;
  • ... ou réduit ou agrandit les images matricielles;
  • ... ou change les valeurs de couleur selon un algorithme spécifique;
  • ... ou il recadre les images, les superpose, les inverse, les reflète;
  • ...et ainsi de suite....

... mais pour imprimer les images manipulées, vous devez utiliser un programme différent.

Certains formats d'image (TIFF, PNG, ...) prennent en charge l'enregistrement interne d'un paramètre DPI dans leurs métadonnées.

Mais il ne s'agit que d'un attribut «conseil» qui ne modifie pas l'image raster sous-jacente. C'est la raison pour laquelle vous avez fait cette découverte:

"Quand je vérifie le fichier, il reste le même."

Ce «conseil» peut éventuellement être évalué automatiquement par des pilotes d’imprimante ou par des programmes de création de pages tels que LaTeX. En l'absence de telles "indications" DPI (ou si elles ne se présentent pas comme prévu par LaTeX), il devrait toujours être possible de donner à LaTeX le droit de rendre toute image donnée sur une page comme on l'attend. to - il faut juste un peu plus de code LaTeX explicite autour de l'image!

Certains autres formats d'image (JPEG (?), BMP, ...) ne permettent même pas de stocker un indice DPI pour leurs métadonnées internes.

Donc, Gimp ne supporte que ce que vous voyez qu'il fait avec "Image -> Taille d'impression" parce qu'il veut imprimer une image. Avec ImageMagick, vous ne pouvez pas imprimer.

Continuez à faire ce que vous voulez faire avec Gimp lorsque vous imprimez. Cela n’a aucun sens avec ImageMagick.

Reportez-vous également à cet extrait de documentation de messagerie instantanée supplémentaire , qui explique le même sujet avec des termes différents.


Donc ce qui reste est ceci:

  • Si vous "manipulez" votre image avec Gimp, puis intégrez le résultat dans LaTeX, la page ressemble à ce que vous attendez.
  • Si vous "manipulez" votre image avec ImageMagick, puis intégrez le résultat dans LaTeX, la page ne ressemble pas à ce que vous attendiez.

Veuillez fournir les éléments suivants pour résoudre le problème ci-dessus:

  • la version exacte de votre installation ImageMagick (sortie complète de convert -versionand convert -list configure);
  • (un lien vers une) image échantillon originale;
  • (un lien vers) la même image manipulée par Gimp;
  • (un lien vers) la même image manipulée par ImageMagick.

De cette façon, nous pouvons aider à résoudre le problème.

Mais remarque: il s'agit d'un problème différent de celui de votre sujet / titre actuel: "Je souhaite modifier le DPI avec Imagemagick sans modifier la taille en octets réelle des données d'image".


Mise à jour

Comme certains lecteurs ne savent toujours pas ce que j'ai noté ci-dessus, voici une autre tentative ...

Tout ce qui est noté comme "Résolution" ou "Densité" dans un fichier image est un attribut de métadonnées . Cela n'a aucune influence sur le nombre de pixels réels décrits par le fichier et n'a aucune pertinence à cet égard. C'est simplement un indice qu'un périphérique d'impression ou de rendu ou une application peut ou non suivre lors de l'impression, du rendu ou de l'affichage de l'image.

À cette fin, il ne s’agit que de quelques chiffres stockés dans le fichier image. Ces chiffres indiquent aux périphériques de sortie tels que les imprimantes et affichent combien de points (ou pixels) par pouce l'image doit être affichée. Pour les formats vectoriels tels que PostScript, PDF, MWF et SVG, il indique l’échelle de pixel pour dessiner les coordonnées du monde réel utilisées par l’image.

Adobe Photoshop est un exemple dans lequel la valeur de résolution indiquée par ImageMagick dans les métadonnées de l'image n'est PAS honorée par une application. Photoshop stocke ses astuces sur la résolution d'impression ou d'affichage souhaitée dans un profil propriétaire nommé 8bim . ImageMagick ne touche pas ce profil, même lorsqu'il vous est demandé d'écrire un changement de résolution dans les métadonnées d'un fichier image. D'autre part, Photoshop ignorera toutes les astuces de résolution stockées par ImageMagick dans le champ de métadonnées par ailleurs standard défini à cet effet dès qu'il verra son propre profil 8bim .

Le PO aurait dû choisir la rubrique:

  • "Je souhaite modifier l'indice de résolution DPI (métadonnées) avec ImageMagick sans modifier le nombre réel de pixels dans l'image"

afin d'éviter tout malentendu ...

Kurt Pfeifle
la source
1
"Quand je vérifie le fichier, il reste le même." C'EST CE QUE JE VEUX. Je ne dis pas dans le texte que cela me surprend. PLEAS a relu ma question ... lentement ... ARGL
Boris Däppen
6
"C'est complètement impossible!" Non c'est possible ... c'est juste que l'image se contracte à l'impression. Ce que j'ai expliqué très en détail dans ma question
Boris Däppen
5
De quoi parlez-vous même. J'ai expliqué mon cas d'utilisation en détail dans la question. Si vous répondez aux questions par leur titre, vous n’aidez personne ici.
Boris Däppen le
4
Votre faille fatale était l’hypothèse de départ: «plus de pixels par zone <==> plus de pixels par image», ce qui n’est vrai que si la zone est constante. Ce n'est pas le cas.
Leo Izen
1
Oui. La résolution DPI n'a de sens que si elle est rendue aux périphériques. Il se trouve également qu’il s’agit d’un champ pouvant être stocké dans un fichier image lorsque cette résolution est pertinente. La question demandait clairement comment changer ce champ sans changer les données de pixels.
Leo Izen