web-dev-qa-db-ja.com

画像データの実際のバイトサイズを変更せずにImageMagickでDPIを変更したい

GIMPには、私がやりたいことを行う非常に簡単な方法があります。ドイツ語のダイアログしかインストールしていませんが、翻訳を試みます。 Picture -> PrintingSizeに行って、いわゆるDPI値として知られているX-ResolutionY-Resolutionを調整することについて話しています。デフォルトでPixel/Inchの形式を選択することもできます。 (ドイツ語では、ダイアログはBild -> Druckgrößeであり、そこにX-AuflösungおよびY-Auflösungがあります)

OK、そこにある値はデフォルトでしばしば72です。私がそれらを例えば300これは、画像がコンピューター上で同じままであるという効果がありますが、印刷した場合、それを見るとより小さくなりますが、すべての詳細はまだそこにあります。印刷された用紙の解像度が高くなります(ただし、サイズは小さくなります...私には問題ありません)。

私はLaTeXで作業しているとき、または最近のUbuntu-Machineでコマンドpdflatexを使用して正確に作業していることがよくあります。上記のプロセスをGIMPで手動で実行すると、すべてが正常に機能します。結果のPDFでは画像が小さく表示されますが、印刷品質は高くなります。

私がやろうとしていることは、GIMPに入り、DPI値を調整するプロセスを自動化することです。 ImageMagickは優れていることが知られており、他の多くのタスクに使用したため、このツールで目標を達成しようとしました。しかし、それは私が望むことをしません。

多くのことを試した後、これは実際には私の友人であるべきコマンドだと思います:

convert input.png -density 300 output.png

Webのどこでも読むことができるので、これはDPIを300に設定するはずです。動作するようです。しかし、ファイルをチェックしても同じままです(編集:上記で説明したように、これは私が期待するものです)。

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

このコマンドを使用すると、私が望んでいたように見えます。

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

おかしなことに、同じ出力がinput.pngについても出てきて混乱を招きます...ですから、これは監視するパラメータとしては間違っているのではないでしょうか?

しかし、TeXをpdflatexでレンダリングすると、画像はまだ大きくぼやけています。また、GIMPで画像を再度開くと、DPI値は72ではなく300に設定されます。したがって、実際にはまったく影響がありませんでした。

ここで問題は何ですか。何かが完全に間違っていますか?すべてがGIMPで問題なく動作するので、私はそれほど間違ったことはありません。

これで助けてくれてありがとう。また、Linuxシステムで簡単に実行できる他の自動化ソリューションも利用できます。

46
Boris Däppen

単位を指定します-このオプションを省略したときに問題があったことを覚えているようです(ただし、DPIがデフォルトであるはずです)。次に例を示します。

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

GIMPが解像度を読み取るために使用する埋め込みデータフィールドを知っていますか?ImageMagickで使用される標準のデータフィールドをオーバーライドする独自のデータフィールドがありますか?たとえば、PhotoshopはPhotoshop:XResolutionおよびPhotoshop:YResolutionしたがって、Photoshopで濃度設定を認識するためにこれらを設定する必要があります(ImageMagickではこれを行うことができません。ExifToolを使用しています)。

77
Martin Wilson

Exiftoolを使用して解像度を読み取ることができます。たとえば、Exiftool '-*resolution*' c.jpg

解像度単位:インチX解像度:300 Y解像度:300

Exiftoolはパラメータを設定することもできますが、Image::ExifTool::TagNamesのマニュアルページに記載されているように、ExifタグXResolutionおよびYResolutionはExiftoolから書き込みできません。

ImageMagickに解像度変更オプションがあるかどうかはわかりませんが、ない場合は驚きます。また、GIMPスクリプトを記述してこのようなタスクを自動化することも簡単です。また、小さなプログラムで解像度を変更することもできます。たとえば、次のCプログラム(gcc setRes.c -O3 -Wall -o setResを介してコンパイル可能)は、jpegファイルの最初の数バイトを読み取り、解像度を300に変更し、それらを書き換えます。示されているプログラムは、x86などのリトルエンディアンマシンの定数を使用しています。ビッグエンディアンのマシンで実行すると、xyz is jpegファイルであっても、Error: xyz may be not a .jpg fileのようなメッセージで終了するはずです。注:pdflatexを使用して結果の画像をテストしていません。 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;
}

convertにメタデータを追加するだけで、[モノクロ]ビットマップを再エンコードしないように説得する方法を理解できませんでした。それはファイルを50%以上拡張していました。

pngcrush(ImageMagickツールではない)でも密度メタデータを追加できることを発見しました。次のコマンドラインは600dpiをマークし、他の最適化を可能にします。これにより、ファイルサイズが約10%削減されました。

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