我想使用 ImageMagick 更改 DPI,而不更改圖像資料的實際位元組大小

我想使用 ImageMagick 更改 DPI,而不更改圖像資料的實際位元組大小

在 GIMP 中,有一個非常簡單的方法可以實現我想要的功能。我只安裝了德語對話,但我會嘗試翻譯它。我說的是要Picture -> PrintingSize調整數值X-ResolutionY-Resolution我稱之為 DPI 值。您也可以選擇預設格式Pixel/Inch。 (德文的對話是Bild -> Druckgrößeand there X-Auflösungand Y-Auflösung

好的,那裡的值通常是72預設的。當我將它們更改為例如300時,圖像在計算機上保持不變,但如果我打印它,如果你看它,它會變小,但所有細節仍然存在,只是變小 - >它有打印紙上的分辨率更高(但尺寸更小......這對我來說很好)。

當我使用 LaTeX 時,或者準確地說,pdflatex在最近的 Ubuntu 機器上使用命令時,我經常這樣做。當我手動使用 GIMP 執行上述過程時,一切正常。產生的 PDF 中的影像會顯得較小,但列印品質較高。

我想做的是自動化進入 GIMP 和調整 DPI 值的過程。由於 ImageMagick 以其卓越的性能而聞名,並且我將它用於許多其他任務,因此我嘗試使用此工具來實現我的目標。但它並沒有達到我想要的效果。

在嘗試了很多事情之後,我認為這實際上是我朋友應該使用的命令:

convert input.png -density 300 output.png

這應該會將 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 系統上輕鬆完成的自動化解決方案持開放態度。

答案1

指定單位 - 我似乎記得當我省略此選項時遇到問題(儘管 DPI 應該是預設值),例如:

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

您知道 GIMP 使用哪些嵌入資料欄位來讀取解析度嗎?例如,Photoshop 使用Photoshop:XResolutionPhotoshop:YResolution因此您必須設定這些以便 Photoshop 識別密度設定(ImageMagick 無法執行此操作 - 我們使用 ExifTool)。

答案2

我不知道如何說服轉變僅添加元資料而不重新編碼我的[單色]點陣圖;檔案擴充>50%。

我發現粉碎(不是 ImageMagick 工具)還可以加入密度元資料。此命令列將其標記為 600dpi 並允許其他最佳化,這將檔案大小減少了約 10%:

pngcrush -res 600 in.png out.png

答案3

請注意,您可以使用 Exiftool 來讀出解析度。例如,Exiftool '-*resolution*' c.jpg可能會顯示

解析度單位:英吋 X 解析度:300 Y 解析度:300

Exiftool 也可以設定參數,但如手冊頁所述Image::ExifTool::TagNames,Exiftool 無法寫入額外標籤 XResolution 和 YResolution。

我不知道 ImageMagick 是否有解析度變更選項,但如果沒有,我會感到驚訝。此外,編寫 GIMP 腳本來自動執行此類任務也很簡單,而且還可以使用小程式更改解析度。例如,以下是一個 C 程式(可透過 編譯gcc setRes.c -O3 -Wall -o setRes),它讀取 jpeg 檔案的前幾個字節,將解析度變更為 300,然後重寫它們。所示程式使用小端機器(例如 x86)的常數。如果在大端機器上運行,它應該以類似 的訊息終止Error: xyz may be not a .jpg file,即使 xyz一個 jpeg 檔案。請注意,我還沒有通過pdflatex;測試生成的圖片。您可能會發現值得在特克斯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;
}

答案4

“我想使用 Imagemagick 更改 DPI,而不更改圖像資料的實際位元組大小。”

這是完全不可能的事!

因為:

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

而且你似乎不明白現實中的 DPI 是什麼:

  1. 這是一個完全抽象的值,只有在知道螢幕或監視器上列印輸出或渲染的絕對大小的情況下才具有實用價值:
    • 您可以在 1 吋寬的正方形上「列印」完全相同的 72x72 像素影像:列印輸出的解析度為72dpi.
    • 您也可以將其「列印」在 1/4 英吋寬的正方形上:然後列印輸出的解析度將為288dpi.
    • 注意:如果您在 1 英寸見方的地方「列印」它288dpi,它就不再是同一個圖像:它將透過印表機驅動程式或其他一些過濾機制進行一些外推,並且它將變成一個288x288 像素的圖像,而不是一個288x288 像素的圖像。
  2. 兩種列印輸出都將具有完全相同的圖像資訊——288dpi 圖像不會突然擁有更多資訊。

如果您想將原始 72x72 像素圖像列印為 1 英寸寬的正方形,但在288dpi,那麼您必須重新縮放圖像(在本例中將其放大)。對於原始影像中的每 1 個像素,您將需要新的放大影像的 4 個像素。現在有不同的演算法可用於計算這 4 個像素(其中 3 個是新像素)應具有的顏色值:

  • 你可以給它們與原始像素相同的值(這是一個非常“原始”的演算法,
  • 或者您可以將原始像素的顏色值與相鄰像素的顏色值進行平均。

無論如何,您都會建立一個由 288 行像素組成的更大影像,每行像素高 288 像素(288x288 像素)。

當您瀏覽「圖片 -> 列印尺寸」時,Gimp 會為您做什麼:它簡化了重新計算絕對像素尺寸所需變化的過程,使其更加用戶友好。以此目的...

  • ……它首先詢問您有關 DPI 的信息,因為給定的印表機無法任意更改其列印分辨率(有些印表機不僅可以提供一種分辨率,甚至可以提供 2 或 3 種不同的分辨率)。因此它會詢問您要以哪種解析度進行列印。這是第一個訊息。
  • ……然後它還要求第二個訊息:列印輸出應以何種尺寸(以cmmm或)出現在紙張上。inch

然後,根據這兩個訊息,Gimp 計算它必須使用的像素總數(從原始像素數推斷)來以請求的分辨率填充請求的空間。

然而,透過使其包含更多像素來放大光柵圖像並不會為其添加真實訊息,而只會為其添加虛構的「品質」。它可能如果你的放大演算法是「好的」演算法,那麼對人眼來說會更好。如果你只是像一些簡單演算法那樣將現有像素加倍、三倍或四倍,那麼它看起來會很難看。

對於光柵影像,
DPI 設定僅在上下文中相關印刷或者顯示它。因為印表機或顯示器已經給了固定的解析度。因此,該資訊僅...

  • ...印表機驅動程式或
  • ...支援列印的影像處理應用程式

需要知道。

ImageMagick 的文檔完全同意我的觀點:

-density width
-density widthxheight
設定影像的水平和垂直分辨率 渲染到設備。

對於向量圖像或檔案格式
(例如 PDF 或 PostScript)DPI 設定在上下文中極為重要光柵化他們。較高的 DPI 會將更多的圖片資訊傳輸為光柵格式,從而保留真實原始品質的更多細節。將 或mm中給定大小的向量影像轉換為具有較高 DPI 的光柵時,將直接轉換為影像中較高的總像素數。cminch

此外,ImageMagick 本身也不支援「列印」。相反,ImageMagick 僅...

  • ...將檔案從給定的光柵格式轉換為其他光柵格式;
  • ……或者它縮小或放大光柵圖像;
  • ……或它根據特定演算法改變顏色值;
  • ……或者它裁剪影像、覆蓋影像、反轉影像、鏡像影像;
  • ....還有什麼-不...

....但要列印處理後的圖像,您需要使用不同的程式。

某些影像格式(TIFF、PNG 等)確實支援在其元資料中內部儲存 DPI 設定。

但這只不過是一個不會改變底層光柵影像的「提示」屬性。這就是您做出此發現的原因:

“當我檢查文件時,它保持不變。”

此「提示」可由印表機驅動程式或頁面建立程式(例如 LaTeX)自動評估。在沒有這樣的 DPI“提示”的情況下(或者如果它們沒有以 LaTeX 期望的方式呈現),LaTeX 仍然應該能夠按照人們期望的方式在頁面上渲染任何給定的圖像- 它只需要一些圍繞圖像更明確的LaTeX 程式碼!

一些其他影像格式(JPEG(?)、BMP...)甚至不支援在其內部元資料中儲存 DPI 提示。

因此,Gimp 只支援您在「圖片 -> 列印尺寸」中看到的內容,因為它想要列印圖像。使用 ImageMagick 您無法列印。

列印時繼續使用 Gimp 做您想做的事情。這對 ImageMagick 來說沒有意義。

也可以看看這個額外的 IM 文件片段,它用不同的詞語解釋了同一主題。


那麼剩下的就是這個:

  • 如果您使用 Gimp “操作”圖像,然後將結果嵌入到 LaTeX 中,頁面看起來就像您期望的那樣。
  • 如果您使用 ImageMagick “操作”圖像,然後將結果嵌入到 LaTeX 中,則頁面看起來如下不是正如你所期望的。

請提供以下資訊來解決上述問題:

  • ImageMagick 安裝的確切版本(convert -version和的完整輸出convert -list configure);
  • (指向)原始樣本圖像的連結;
  • (連結到)由 Gimp 處理的相同圖像;
  • (指向該圖像的連結)由 ImageMagick 操作的相同圖像。

這樣我們就可以幫忙解決問題。

但請注意:這與您當前的主題/標題提出的問題不同:“我想使用 Imagemagick 更改 DPI,而不更改圖像資料的實際位元組大小”


更新

因為它是仍然有些讀者不清楚我上面提到的內容,這裡還有一次嘗試...

無論被標記為'解決'或者'密度'在圖像檔案中,是一個元資料屬性。它對文件描述的實際像素數沒有影響,並且在這方面完全不相關。它只是一個暗示列印或渲染設備或應用程式可以或者可能不會列印、渲染或顯示影像時請遵循。

為此,它只是儲存在圖像檔案中的幾個數字。這些數字告訴印表機等輸出設備,並顯示每英吋影像應顯示多少個點(或像素)。對於 PostScript、PDF、MWF 和 SVG 等向量格式,它告訴像素比例繪製圖像使用的任何現實世界座標。

一個範例,ImageMagick 在影像元資料中記錄的解析度值為不是獲此殊榮的應用程式是Adobe Photoshop。 Photoshop 將所需列印或顯示解析度的提示儲存於名為8bim。即使要求將解析度變更寫入影像檔案的元資料中,ImageMagick 也不會觸及此設定檔。另一方面,Photoshop 一旦看到自己的解析度提示,就會忽略 ImageMagick 在為此目的定義的其他標準元資料欄位中儲存的所有解析度提示8bim輪廓。

OP應該選擇標題:

  • “我想使用 ImageMagick 更改 DPI(元數據分辨率提示),而不更改圖像中的實際像素數”

為了避免一切誤會...

相關內容