Voglio cambiare DPI con ImageMagick senza cambiare la dimensione in byte effettiva dei dati dell'immagine


45

In GIMP c'è un modo molto semplice per fare ciò che voglio. Ho installato solo la finestra di dialogo tedesca, ma proverò a tradurla. Sto parlando di andare Picture -> PrintingSizee quindi di regolare i valori X-Resolutione Y-Resolutionche sono noti per me come i cosiddetti valori DPI. Puoi anche scegliere il formato predefinito Pixel/Inch. (In tedesco la finestra di dialogo è Bild -> Druckgrößee lì X-Auflösunge Y-Auflösung)

Ok, i valori ci sono spesso 72di default. Quando le cambio ad esempio, 300questo ha l'effetto che l'immagine rimanga la stessa sul computer, ma se la stampa, sarà più piccola se la guardi, ma tutti i dettagli sono ancora lì, solo più piccoli -> ha una risoluzione più elevata sulla carta stampata (ma di dimensioni inferiori ... che per me va bene).

Lo faccio spesso quando lavoro con LaTeX o, per essere precisi, con il comando pdflatexsu una macchina Ubuntu recente. Quando eseguo manualmente il processo sopra descritto con GIMP, tutto funziona perfettamente. Le immagini appariranno più piccole nel PDF risultante ma con alta qualità di stampa.

Quello che sto cercando di fare è automatizzare il processo di accesso a GIMP e la regolazione dei valori DPI. Poiché ImageMagick è noto per essere eccezionale e l'ho usato per molte altre attività, ho cercato di raggiungere il mio obiettivo con questo strumento. Ma non fa proprio quello che voglio.

Dopo aver provato molte cose, penso che questo sia effettivamente il comando che dovrebbe essere mio amico:

convert input.png -density 300 output.png

Questo dovrebbe impostare il DPI su 300, come posso leggere ovunque nel web. Sembra funzionare Ma quando controllo il file rimane lo stesso (EDIT: che è quello che mi aspetto, come spiegato sopra).

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

Quando uso questo comando, sembra che abbia fatto quello che volevo:

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

Abbastanza divertente, lo stesso output viene per il input.pngquale mi confonde ... quindi questo potrebbe essere i parametri sbagliati da guardare?

Ma quando ora rendering il mio TeX con pdflatexl'immagine è ancora grande e sfocata. Inoltre, quando apro di nuovo l'immagine con GIMP, i valori DPI vengono impostati su 72anziché 300. Quindi in realtà non c'è stato alcun effetto.

Ora qual è il problema qui. Sto sbagliando qualcosa? Non posso sbagliarmi dal momento che tutto funziona perfettamente con GIMP.

Grazie per l'aiuto in questo. Sono aperto anche ad altre soluzioni automatizzate che possono essere facilmente eseguite su un sistema Linux.


user1694803: Dovresti ricordarti di tornare alla risposta di Martin Wilson e anche di "votarla" (fai clic sulla piccola ^icona a sinistra della sua risposta), non solo di "accettarla" non appena hai abbastanza reputazione personale (penso che tu abbia bisogno di +15) ...
Kurt Pfeifle,

Risposte:


76

Specifica le unità: mi sembra di ricordare di avere avuto un problema quando ho omesso questa opzione (sebbene DPI debba essere l'impostazione predefinita), ad esempio:

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

Sai quali campi di dati incorporati utilizza GIMP per leggere la risoluzione - ha i suoi che sovrascrivono quelli standard usati da ImageMagick? Ad esempio, Photoshop utilizza Photoshop:XResolutione Photoshop:YResolutionquindi è necessario impostare questi per Photoshop per riconoscere un'impostazione di densità (ImageMagick non può farlo - usiamo ExifTool).


2
Ho dovuto mettere -density 300prima input.png. Stavo convertendo PDF. Grazie comunque.
Akostadinov,

Per la conversione da PNG a TIFF che dovevo usare -set units PixelsPerInch -density 300, simple -unitsnon funzionava indipendentemente dall'ordine delle opzioni.
Andrey,

5

Nota che puoi usare Exiftool per leggere le risoluzioni. Ad esempio, Exiftool '-*resolution*' c.jpgpotrebbe mostrare

Unità di risoluzione: pollici X Risoluzione: 300 Y Risoluzione: 300

Exiftool è anche in grado di impostare i parametri, ma come notato nella pagina man Image::ExifTool::TagNames, i tag extra XResolution e YResolution non sono scrivibili da Exiftool.

Non so se ImageMagick abbia opzioni di modifica della risoluzione, ma sarei sorpreso se non lo facesse. Inoltre, è semplice scrivere script GIMP per automatizzare attività come questa, ed è anche possibile cambiare le risoluzioni con piccoli programmi. Ad esempio, di seguito è riportato un programma C (compilabile tramite gcc setRes.c -O3 -Wall -o setRes) che legge i primi byte di un file jpeg, modifica le risoluzioni su 300 e le riscrive. Il programma come mostrato usa costanti per macchine little-endian, come x86. Se eseguito su una macchina big-endian, dovrebbe terminare con un messaggio simile Error: xyz may be not a .jpg file, anche se xyz è un file jpeg. Nota, non ho testato le immagini risultanti tramite pdflatex; probabilmente troverai utile pubblicare una domanda nel 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;
}

1
Questo non mi aiuta molto, dal momento che ho a che fare con PNG e non ho molto indizio di JPG o anche di C. Questo è per conoscenza "profonda" per me essere utile. Forse qualcun altro può usarlo.
Boris Däppen,

Sì, avrei dovuto prestare maggiore attenzione alla domanda! Rileggendolo, JPG non è menzionato, PNG chiaramente lo è.
James Waldby - jwpat7,

Sì, sono qualcun altro e posso usarlo: ho aperto il mio file .jpg in un editor esadecimale e ho modificato il nono e l'undicesimo byte per la densità verticale e orizzontale. Per così dire, ho "eseguito" il tuo codice manualmente.
u_Ltd.

2

Non sono riuscito a capire come convincere convert per aggiungere solo i metadati e non ricodificare la mia bitmap [monocromatica]; stava espandendo il file> 50%.

Ho scoperto che pngcrush (non uno strumento ImageMagick) può anche aggiungere i metadati di densità. Questa riga di comando lo contrassegna 600 dpi e consente altre ottimizzazioni, che hanno ridotto le dimensioni del file del 10% circa:

pngcrush -res 600 in.png out.png

-1

"Voglio cambiare DPI con Imagemagick senza cambiare la dimensione effettiva dei byte dei dati dell'immagine."

Questo è completamente impossibile!

Perché:

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

Inoltre non sembra capire quale DPI sia in realtà:

  1. È un valore completamente astratto che ottiene valore pratico solo nel contesto della conoscenza anche della dimensione assoluta della stampa o del rendering su schermo o monitor:
    • Puoi 'stampare' la stessa immagine di 72x72 pixel su un quadrato largo 1 pollice: la stampa avrà una risoluzione di 72dpi.
    • Puoi 'stamparlo' anche su un quadrato largo 1/4 di pollice: quindi la stampa avrà una risoluzione di 288dpi.
    • ( Nota: se lo 'stampi' 288dpisu un quadrato da 1 pollice, non è più la stessa immagine: avrà subito qualche estrapolazione attraverso il driver della stampante o qualche altro meccanismo di filtraggio e sarà diventata un'immagine di 288x288 pixel anziché un'immagine di 72x72 pixel ... )
  2. Entrambe le stampe avranno le stesse informazioni sull'immagine - l'immagine a 288 dpi non ne avrà improvvisamente di più.

Se vuoi stampare l'immagine originale di 72x72 pixel come un quadrato largo 1 pollice, ma a 288dpi, dovrai ridimensionare l'immagine (in questo caso ridimensionandola). Per ogni 1 pixel nell'originale sono necessari 4 pixel della nuova immagine ingrandita. Ora ci sono diversi algoritmi che possono essere utilizzati per calcolare quali valori di colore dovrebbero avere questi 4 pixel (3 dei quali nuovi pixel):

  • potresti dare loro lo stesso pixel originale (che è un algoritmo molto "grezzo",
  • oppure potresti fare una media del valore di colore del pixel originale con i valori di colore dei pixel vicini.

In ogni caso stai creando un'immagine più grande composta da 288 righe di pixel alte 288 pixel ciascuna (288x288 pixel).

Cosa fa Gimp per te quando passi da "Immagine -> Dimensione stampa": semplifica il processo di ricalcolo delle modifiche richieste in dimensioni assolute dei pixel, rendendolo più facile da usare. Per questo scopo...

  • ... ti chiede prima del DPI perché una determinata stampante non può cambiare arbitrariamente la sua risoluzione di stampa (alcune possono offrire non solo una, ma forse anche 2 o 3 risoluzioni diverse). Quindi ti chiede a quale risoluzione vuoi stampare. Questa è la prima informazione.
  • ... quindi chiede anche il secondo pezzo: a quale formato (in cm, mmo inch) la stampa dovrebbe apparire sulla carta.

Secondo queste due informazioni, Gimp calcola quindi il numero totale di pixel che deve usare (estrapolare dal numero originale di pixel) per riempire lo spazio richiesto alla risoluzione richiesta.

Tuttavia, il ridimensionamento di un'immagine raster facendola contenere più pixel non aggiunge informazioni reali ad essa e aggiunge solo "qualità" a ciò che è fittizio. Può sembrare più bello per l'occhio umano se il tuo algoritmo di ingrandimento è "buono". E sembrerà brutto se raddoppiate, triplicate o quadruplicate i pixel esistenti, come fanno alcuni semplici algoritmi.

Per le immagini raster,
l'impostazione DPI è rilevante solo nel contesto della stampa o della visualizzazione . Perché stampanti o monitor hanno dato risoluzioni fisse. Pertanto sono informazioni che solo ...

  • ... un driver della stampante o
  • ... un'applicazione di elaborazione delle immagini che supporta la stampa

bisogno di sapere.

E la documentazione di ImageMagick è in pieno accordo con me:

-density width
-density widthxheight
Imposta la risoluzione orizzontale e verticale di un'immagine per il rendering su dispositivi.

Per immagini vettoriali o formati di file
(come PDF o PostScript), l'impostazione DPI è tuttavia estremamente importante nel contesto dellaloro rasterizzazione . Un DPI più elevato trasferirà più informazioni sull'immagine nel formato raster e quindi preserverà più dettagli dalla reale qualità originale. Quando si converte un'immagine vettoriale di una data dimensione dimm,cmoinchin raster con un più alto DPI sarà direttamente traduce in un maggior numero di pixel totali nell'immagine.

Inoltre, ImageMagick non supporta la "stampa" in quanto tale. Invece, solo ImageMagick ...

  • ... converte i file da un determinato formato raster in altri formati raster;
  • ... oppure ridimensiona o ingrandisce le immagini raster;
  • ... oppure cambia i valori di colore secondo un algoritmo specifico;
  • ... oppure ritaglia immagini, le sovrappone, le inverte, le riflette;
  • ... e cosa no ....

... ma per stampare le immagini manipolate, è necessario utilizzare un programma diverso.

Alcuni formati di immagine (TIFF, PNG, ...) supportano la memorizzazione interna di un'impostazione DPI nei loro metadati.

Ma questo non è altro che un attributo 'suggerimento' che non altera l'immagine raster sottostante. Questo è il motivo per cui hai fatto questa scoperta:

"Quando controllo il file rimane lo stesso."

Questo "suggerimento" può essere valutato automaticamente dai driver della stampante o dai programmi di creazione di pagine come LaTeX. In assenza di tali 'suggerimenti' DPI (o se in qualche modo non si presentano nel modo in cui LaTeX si aspetta che facciano), LaTeX dovrebbe comunque essere in grado di comandare di eseguire il rendering di una determinata immagine su una pagina come ci si aspetta a - ha bisogno solo di un codice LaTeX più esplicito attorno all'immagine!

Alcuni altri formati di immagine (JPEG (?), BMP, ...) non supportano nemmeno la memorizzazione di un suggerimento DPI nei loro metadati interni.

Quindi Gimp supporta solo ciò che vedi che sta facendo con "Immagine -> Dimensione di stampa" perché vuole stampare un'immagine. Con ImageMagick non è possibile stampare.

Continua a fare quello che vuoi fare con Gimp durante la stampa. Non ha senso con ImageMagick.

Vedi anche questo ulteriore frammento di documentazione IM , che spiega lo stesso argomento in parole diverse.


Quindi ciò che rimane è questo:

  • Se "manipoli" la tua immagine con Gimp e poi incorpori il risultato in LaTeX, la pagina sembra come te l'aspetti.
  • Se 'manipoli' la tua immagine con ImageMagick e poi incorpori il risultato in LaTeX, la pagina non sembra come ti aspetti.

Fornisci quanto segue per risolvere il problema sopra riportato:

  • la versione esatta dell'installazione di ImageMagick (output completo di convert -versione convert -list configure);
  • (un collegamento a) un'immagine di esempio originale;
  • (un collegamento alla) stessa immagine manipolata da Gimp;
  • (un collegamento alla) stessa immagine manipolata da ImageMagick.

In questo modo possiamo aiutare a risolvere il problema.

Ma nota: questo è un problema diverso da quello che il tuo soggetto / titolo attuale chiede: "Voglio cambiare DPI con Imagemagick senza cambiare l'effettiva dimensione in byte dei dati dell'immagine"


Aggiornare

Dal momento che non è ancora chiaro ad alcuni lettori ciò che ho notato sopra, ecco un altro tentativo ...

Qualunque cosa si noti come "Risoluzione" o "Densità" all'interno di un file di immagine, è un attributo di metadati . Non ha alcuna influenza sul numero di pixel effettivi descritti dal file ed è completamente irrilevante al riguardo. È solo un suggerimento che un dispositivo di stampa o rendering o un'applicazione possono seguire o meno durante la stampa, il rendering o la visualizzazione dell'immagine.

A tal fine, è solo un numero memorizzato nel file di immagine. Questi numeri indicano i dispositivi di output come le stampanti e mostrano il numero di punti (o pixel) per pollice in cui deve essere visualizzata l'immagine. Per formati vettoriali come PostScript, PDF, MWF e SVG indica alla scala di pixel di disegnare tutte le coordinate del mondo reale utilizzate dall'immagine.

Un esempio, in cui il valore di risoluzione annotato da ImageMagick all'interno dei metadati dell'immagine NON è onorato da un'applicazione è Adobe Photoshop. Photoshop memorizza i suoi suggerimenti su una risoluzione di stampa o di visualizzazione desiderata in un profilo proprietario denominato 8bim . ImageMagick non tocca questo profilo, anche quando viene chiesto di scrivere una modifica di risoluzione nei metadati di un file di immagine. Photoshop d'altra parte, ignorerà tutti i suggerimenti di risoluzione memorizzati da ImageMagick nel campo dei metadati altrimenti standard definito a questo scopo non appena vede il proprio profilo 8bim .

Il PO avrebbe dovuto scegliere la rubrica:

  • "Voglio cambiare DPI (suggerimento per la risoluzione dei metadati) con ImageMagick senza cambiare il numero effettivo di pixel nell'immagine"

al fine di evitare tutti i malintesi ...


1
"Quando controllo il file rimane lo stesso." QUESTO È QUELLO CHE VOGLIO. NON DICO NEL TESTO CHE QUESTO SORPRENDE. PER
FAVORE

6
"Questo è completamente impossibile!" No è possibile ... è solo che l'immagine si restringe quando viene stampata. Che ho spiegato in modo molto dettagliato nella mia domanda
Boris Däppen,

5
Di cosa stai persino parlando. Ho spiegato il mio caso d'uso in dettaglio all'interno della domanda. Se rispondi alle domande solo per titolo non sei di aiuto a nessuno qui.
Boris Däppen il

4
Il tuo fatale difetto era l'assunto iniziale: "più pixel per area <==> più pixel totali per immagine" Questo è vero solo se l'area è costante. Questo non è il caso.
Leo Izen,

1
Sì. DPI è significativo solo se reso ai dispositivi. Capita anche di essere un campo che può essere memorizzato in un file di immagine per quando questa risoluzione è rilevante. La domanda poneva chiaramente come modificare questo campo senza modificare i dati dei pixel.
Leo Izen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.