Ich möchte DPI mit ImageMagick ändern, ohne die tatsächliche Bytegröße der Bilddaten zu ändern

45

In GIMP gibt es eine sehr einfache Möglichkeit, das zu tun, was ich will. Ich habe nur den deutschen Dialog installiert, aber ich werde versuchen, ihn zu übersetzen. Ich spreche über zu gehen Picture -> PrintingSizeund dann die Werte eingestellt X-Resolutionund Y-Resolutiondie als so genannte DPI - Werte mir bekannt sind. Sie können auch das Standardformat auswählen Pixel/Inch. (Auf deutsch ist der Dialog Bild -> Druckgrößeund da X-Auflösungund Y-Auflösung)

Ok, die Werte dort sind oft 72voreingestellt. Wenn ich sie in z. B. ändere, 300hat dies zur Folge, dass das Bild auf dem Computer gleich bleibt, aber wenn ich es drucke, wird es kleiner, wenn Sie es betrachten, aber alle Details sind noch vorhanden, nur kleiner -> es hat eine höhere Auflösung auf dem gedruckten Papier (aber kleiner ... das ist in Ordnung für mich).

Ich mache das oft, wenn ich mit LaTeX arbeite, oder um genau zu sein, mit dem Befehl pdflatexauf einer aktuellen Ubuntu-Maschine. Wenn ich den obigen Vorgang mit GIMP manuell durchführe, funktioniert alles einwandfrei. Die Bilder erscheinen im resultierenden PDF kleiner, aber mit hoher Druckqualität.

Was ich versuche zu tun, ist, den Prozess zu automatisieren, in GIMP zu gehen und die DPI-Werte anzupassen. Da ImageMagick bekanntermaßen hervorragend ist und ich es für viele andere Aufgaben verwendete, versuchte ich, mein Ziel mit diesem Tool zu erreichen. Aber es macht einfach nicht was ich will.

Nachdem ich viele Dinge ausprobiert habe, denke ich, dass dies tatsächlich der Befehl ist, der mein Freund sein sollte:

convert input.png -density 300 output.png

Dies sollte die DPI auf 300 setzen, da ich überall im Web lesen kann. Es scheint zu funktionieren. Aber wenn ich die Datei überprüfe, bleibt sie gleich (BEARBEITEN: das ist, was ich erwarte, wie oben erklärt).

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

Wenn ich diesen Befehl verwende, hat er anscheinend das getan, was ich wollte:

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

Komischerweise kommt derselbe Ausgang für input.pngden ich verwirrt bin ... also sind dies möglicherweise die falschen Parameter, die ich beobachten muss?

Aber wenn ich jetzt mein TeX mit pdflatexdem Bild rendere, ist es immer noch groß und verschwommen. Auch wenn ich das Bild mit GIMP wieder öffne, werden die DPI-Werte auf 72anstatt gesetzt 300. Es gab also überhaupt keine Wirkung.

Was ist hier das Problem? Verstehe ich etwas völlig falsch? Ich kann nicht so falsch liegen, da mit GIMP alles in Ordnung ist.

Vielen Dank für jede Hilfe. Ich bin auch offen für andere automatisierte Lösungen, die auf einem Linux-System leicht zu realisieren sind.

Boris Däppen
quelle
user1694803: Sie sollten daran denken, zu Martin Wilsons Antwort zurückzukehren und sie ebenfalls zu "stimmen" (klicken Sie auf das kleine ^Symbol links von seiner Antwort), und sie nicht nur zu "akzeptieren", sobald Sie genug persönlichen Ruf haben (ich denke, Sie brauchen ihn) +15) ...
Kurt Pfeifle

Antworten:

76

Angabe der Einheiten - Ich kann mich an ein Problem erinnern, als ich diese Option weggelassen habe (obwohl DPI die Standardeinstellung sein sollte), zum Beispiel:

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

Wissen Sie, welche eingebetteten Datenfelder GIMP zum Lesen der Auflösung verwendet? Hat es eigene Felder, die die von ImageMagick verwendeten Standardfelder außer Kraft setzen? Zum Beispiel Photoshop verwendet Photoshop:XResolutionund Photoshop:YResolutionso müssen Sie diese Set für Photoshop eine Dichteeinstellung (ImageMagick nicht tun kann dies - wir verwenden ExifTool) zu erkennen.

Martin Wilson
quelle
2
Ich musste -density 300vorher setzen input.png. Ich habe PDFs konvertiert. Danke trotzdem.
akostadinov
Für die Konvertierung von PNG in TIFF musste ich -set units PixelsPerInch -density 300einfach verwenden , es -unitsfunktionierte nicht, unabhängig von der Reihenfolge der Optionen.
Andrey
5

Beachten Sie, dass Sie mit Exiftool Auflösungen auslesen können. Zum Beispiel Exiftool '-*resolution*' c.jpgkönnte zeigen

Auflösungseinheit: Zoll X Auflösung: 300 Y Auflösung: 300

Exiftool kann auch Parameter festlegen, aber wie in der Manpage angegeben Image::ExifTool::TagNames, können die zusätzlichen Tags XResolution und YResolution nicht von Exiftool geschrieben werden.

Ich weiß nicht, ob ImageMagick über Optionen zum Ändern der Auflösung verfügt, würde mich aber wundern, wenn dies nicht der Fall ist. Es ist auch einfach, GIMP-Skripte zu schreiben, um Aufgaben wie diese zu automatisieren, und es ist auch möglich, Auflösungen mit kleinen Programmen zu ändern. Es folgt beispielsweise ein C-Programm (über gcc setRes.c -O3 -Wall -o setResdas kompiliert werden kann ), das die ersten Bytes einer JPEG-Datei liest, die Auflösung in 300 ändert und sie neu schreibt. Das gezeigte Programm verwendet Konstanten für Little-Endian-Maschinen wie x86. Wenn auf einer Big-Endian - Maschine laufen soll es mit einer Meldung beenden , wie Error: xyz may be not a .jpg file, auch wenn xyz ist eine JPEG - Datei. Beachten Sie, dass ich die resultierenden Bilder nicht über getestet habe pdflatex. es würde sich wahrscheinlich lohnen, eine frage in die tex se zu stellen .

/* 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
quelle
1
Das hilft mir nicht viel, da ich mit PNG zu tun habe und nicht viel Ahnung von JPG oder sogar C. Das ist zu "tiefes" Wissen, um nützlich zu sein. Vielleicht kann jemand anderes es benutzen.
Boris Däppen
Ja, ich hätte der Frage mehr Aufmerksamkeit schenken sollen! Beim erneuten Lesen wird JPG nicht erwähnt, PNG ist es eindeutig.
James Waldby - jwpat7
Ja, ich bin jemand anderes und kann es verwenden: Ich habe meine JPG-Datei in einem Hex-Editor geöffnet und das neunte und elfte Byte für die vertikale und horizontale Dichte bearbeitet. Sozusagen habe ich Ihren Code manuell "ausgeführt".
u_Ltd.
2

Ich konnte nicht herausfinden, wie ich die Konvertierung davon überzeugen kann , nur die Metadaten hinzuzufügen und meine [monochrome] Bitmap nicht neu zu kodieren. Die Datei wurde um mehr als 50% erweitert.

Ich habe festgestellt, dass pngcrush (kein ImageMagick-Tool) auch die Dichtemetadaten hinzufügen kann. Diese Befehlszeile markiert es mit 600 dpi und ermöglicht andere Optimierungen, durch die die Dateigröße um ~ 10% reduziert wurde:

pngcrush -res 600 in.png out.png
Charles Boling
quelle
-1

"Ich möchte DPI mit Imagemagick ändern, ohne die tatsächliche Bytegröße der Bilddaten zu ändern."

Das ist völlig unmöglich!

Weil:

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

Sie scheinen auch nicht zu verstehen, was DPI in Wirklichkeit ist:

  1. Es ist ein völlig abstrakter Wert, der nur dann einen praktischen Wert erhält, wenn man auch die absolute Größe des Ausdrucks oder Renderings auf dem Bildschirm oder Monitor kennt:
    • Sie können dasselbe 72 x 72 Pixel große Bild auf ein 1 Zoll breites Quadrat 'drucken': Der Ausdruck hat eine Auflösung von 72dpi.
    • Sie können es auch auf ein 1/4-Zoll-Quadrat 'drucken': Der Ausdruck hat dann eine Auflösung von 288dpi.
    • ( Hinweis: Wenn Sie es 288dpiauf einem 1-Zoll-Quadrat "drucken" , ist es nicht mehr dasselbe Bild: Es wurde durch den Druckertreiber oder einen anderen Filtermechanismus extrapoliert und ist stattdessen ein 288 x 288 Pixel großes Bild ein 72x72 Pixel großes Bild ... )
  2. Beide Ausdrucke enthalten die gleichen Bildinformationen - das 288-dpi-Bild enthält nicht plötzlich mehr.

Wenn Sie das Originalbild mit 72 x 72 Pixeln als 1 Zoll breites Quadrat drucken möchten, aber um 288dpi, müssen Sie das Bild neu skalieren (in diesem Fall vergrößern). Für jedes Pixel im Original benötigen Sie 4 Pixel des neuen, hochskalierten Bildes. Nun gibt es verschiedene Algorithmen, mit denen berechnet werden kann, welche Farbwerte diese 4 Pixel (3 davon neue Pixel) haben sollten:

  • Sie könnten sie das gleiche wie das ursprüngliche Pixel geben (was ein sehr "roher" Algorithmus ist,
  • Oder Sie können den Farbwert des Originalpixels mit den Farbwerten der benachbarten Pixel mitteln.

In jedem Fall erstellen Sie ein größeres Bild, das aus 288 Pixelzeilen besteht, die jeweils 288 Pixel hoch sind (288 x 288 Pixel).

Was Gimp für Sie tut, wenn Sie "Bild -> Druckgröße" durchgehen: Es vereinfacht den Prozess der Neuberechnung der erforderlichen Änderungen der absoluten Pixelgrößen und macht es benutzerfreundlicher. Für diesen Zweck...

  • ... fragt Sie zuerst nach der DPI, da ein bestimmter Drucker seine Druckauflösung nicht beliebig ändern kann (einige können nicht nur eine, sondern sogar 2 oder 3 verschiedene Auflösungen anbieten). Sie werden also gefragt, mit welcher Auflösung Sie drucken möchten. Das ist die erste Info.
  • ... dann fragt es auch für das zweite Stück Info: bei welcher Größe (in cm, mmoder inch) der Ausdruck auf Papier erscheinen soll.

Nach diesen beiden Informationen berechnet Gimp dann die Gesamtzahl der Pixel, die es verwenden muss (aus der ursprünglichen Pixelzahl extrapolieren), um den angeforderten Platz mit der angeforderten Auflösung auszufüllen.

Wenn Sie jedoch ein Rasterbild vergrößern, indem Sie es mehr Pixel enthalten, werden keine echten Informationen hinzugefügt, und es wird nur eine fiktive Qualität hinzugefügt. Für das menschliche Auge mag es besser aussehen , wenn Ihr Scale-up-Algorithmus "gut" ist. Und es wird hässlich aussehen, wenn Sie vorhandene Pixel einfach verdoppeln, verdreifachen oder vervierfachen, wie dies bei einigen einfachen Algorithmen der Fall ist.

Bei Rasterbildern ist
die DPI-Einstellung nur beim Drucken oder Anzeigen relevant. Weil Drucker oder Monitore vorgegeben haben, feste Auflösungen. Deshalb ist es Info, dass nur ...

  • ... einen Druckertreiber oder
  • ... eine Bildverarbeitungsanwendung, die das Drucken unterstützt

muss wissen.

Und die Dokumentation von ImageMagick stimmt voll und ganz mit mir überein:

-density width
-density widthxheight
Legen Sie die horizontale und vertikale Auflösung eines Bildes für das Rendern auf Geräten fest.

Für Vektorgrafiken oder Dateiformate
(wie PDF oder PostScript) ist die DPI-Einstellung jedoch äußerst wichtig, um sie zu rastern . Ein höherer DPI-Wert überträgt mehr Bildinformationen in das Rasterformat und bewahrt so mehr Details von der tatsächlichen Originalqualität. Wenn Sie ein Vektorbild einer bestimmten Größe inoderin ein Raster mit einer höheren DPIkonvertierenmm,wird dies direkt in eine höhere Anzahl von Gesamtpixeln im Bild umgesetzt.cminch

Außerdem unterstützt ImageMagick das Drucken als solches nicht. Stattdessen nur ImageMagick ...

  • ... konvertiert Dateien aus einem bestimmten Rasterformat in andere Rasterformate;
  • ... oder verkleinert oder vergrößert Rasterbilder;
  • ... oder es ändert die Farbwerte nach einem bestimmten Algorithmus;
  • ... oder es beschneidet Bilder, überlagert sie, kehrt sie um, spiegelt sie;
  • ...und was nicht....

... aber um die manipulierten Bilder auszudrucken, müssen Sie ein anderes Programm verwenden.

Einige Bildformate (TIFF, PNG, ...) unterstützen das interne Speichern einer DPI-Einstellung in ihren Metadaten.

Dies ist jedoch nur ein Hinweis, der das zugrunde liegende Rasterbild nicht verändert. Das ist der Grund, warum Sie diese Entdeckung gemacht haben:

"Wenn ich die Datei überprüfe, bleibt sie gleich."

Dieser "Hinweis" kann möglicherweise automatisch von Druckertreibern oder Seitenerstellungsprogrammen wie LaTeX ausgewertet werden. Ohne solche DPI-Hinweise (oder wenn sie sich nicht so präsentieren, wie es LaTeX erwartet), sollte LaTeX in der Lage sein, ein bestimmtes Bild auf einer Seite so wiederzugeben, wie man es erwartet zu - es braucht nur etwas mehr expliziten LaTeX-Code um das Bild!

Einige andere Bildformate (JPEG (?), BMP, ...) unterstützen nicht einmal das Speichern eines DPI-Hinweises auf ihre internen Metadaten.

Daher unterstützt Gimp nur das, was Sie mit "Bild -> Druckgröße" sehen, da es ein Bild drucken möchte. Mit ImageMagick können Sie nicht drucken.

Machen Sie weiter mit Gimp, was Sie wollen, wenn Sie drucken. Bei ImageMagick ergibt das keinen Sinn.

Siehe auch dieses zusätzliche IM-Dokumentations-Snippet , in dem dasselbe Thema mit anderen Worten erklärt wird.


Was also bleibt, ist folgendes:

  • Wenn Sie Ihr Bild mit Gimp "manipulieren" und das Ergebnis dann in LaTeX einbetten, sieht die Seite so aus, wie Sie es erwarten.
  • Wenn Sie Ihr Bild mit ImageMagick "manipulieren" und das Ergebnis dann in LaTeX einbetten, sieht die Seite anders aus, als Sie es erwarten.

Bitte geben Sie Folgendes an, um das oben genannte Problem zu beheben:

  • die genaue Version Ihrer ImageMagick-Installation (vollständige Ausgabe von convert -versionund convert -list configure);
  • (ein Link zu einem) Original-Beispielbild;
  • (ein Link zum) selben Bild, das von Gimp manipuliert wurde;
  • (ein Link zum) selben Bild, das von ImageMagick manipuliert wurde.

Auf diese Weise können wir helfen, das Problem zu lösen.

Aber beachten Sie: Dies ist ein anderes Problem als das, was Ihr aktuelles Thema / Ihre Überschrift fragt: "Ich möchte DPI mit Imagemagick ändern, ohne die tatsächliche Bytegröße der Bilddaten zu ändern."


Aktualisieren

Da einigen Lesern immer noch nicht klar ist, was ich oben notiert habe, ist hier ein weiterer Versuch ...

Was in einer Bilddatei als "Auflösung" oder "Dichte" angegeben ist, ist ein Metadatenattribut . Sie hat keinen Einfluss auf die Anzahl der tatsächlich von der Datei beschriebenen Pixel und ist in dieser Hinsicht völlig irrelevant. Es handelt sich lediglich um einen Hinweis, dem ein Druck- oder Renderinggerät oder eine Anwendung beim Drucken, Rendern oder Anzeigen des Bildes folgen kann oder nicht .

Zu diesem Zweck sind nur einige wenige Nummern in der Bilddatei gespeichert. Diese Zahlen geben Auskunft über Ausgabegeräte wie Drucker und zeigen an, wie viele Punkte (oder Pixel) pro Zoll das Bild angezeigt werden soll. Bei Vektorformaten wie PostScript, PDF, MWF und SVG weist die Pixelskala an, alle vom Bild verwendeten Koordinaten der realen Welt zu zeichnen.

Ein Beispiel, bei dem der von ImageMagick in den Bildmetadaten festgestellte Auflösungswert von einer Anwendung NICHT berücksichtigt wird, ist Adobe Photoshop. Photoshop speichert seine Hinweise zu einer gewünschten Druck- oder Anzeigeauflösung in einem proprietären Profil mit dem Namen 8bim . ImageMagick berührt dieses Profil nicht, auch wenn Sie aufgefordert werden, eine Auflösungsänderung in die Metadaten einer Bilddatei zu schreiben. Photoshop hingegen ignoriert alle von ImageMagick in dem für diesen Zweck definierten Standard-Metadatenfeld gespeicherten Auflösungshinweise, sobald es sein eigenes 8bim- Profil sieht .

Das OP sollte die Überschrift gewählt haben:

  • "Ich möchte mit ImageMagick die DPI (Metadaten-Auflösung) ändern, ohne die tatsächliche Anzahl der Pixel im Bild zu ändern."

um alle missverständnisse zu vermeiden ...

Kurt Pfeifle
quelle
1
"Wenn ich die Datei überprüfe, bleibt sie gleich." DAS IST WAS ICH WILL. Ich sage nicht im Text, dass dies mich überrascht. BITTE LESEN SIE MEINE FRAGE WIEDER ... LANGSAM ... ARGL
Boris Däppen
6
"Das ist völlig unmöglich!" Nein, es ist möglich ... es ist nur so, dass das Bild beim Drucken schrumpft. Was ich in meiner Frage sehr ausführlich erklärt habe
Boris Däppen
5
Wovon redest du überhaupt? Ich habe meinen Anwendungsfall in der Frage ausführlich erklärt. Wenn Sie Fragen nur nach dem Titel beantworten, sind Sie hier für niemanden eine Hilfe.
Boris Däppen
4
Ihr schwerwiegender Fehler war die ursprüngliche Annahme: "mehr Pixel pro Fläche <==> mehr Gesamtpixel pro Bild". Dies gilt nur, wenn die Fläche konstant ist. Das ist nicht der Fall.
Leo Izen
1
Ja. DPI ist nur dann sinnvoll, wenn es auf Geräten wiedergegeben wird. Es ist auch ein Feld, das in einer Bilddatei gespeichert werden kann, wenn diese Auflösung relevant ist. Die Frage war eindeutig, wie dieses Feld geändert werden kann, ohne die Pixeldaten zu ändern.
Leo Izen