Я хочу изменить DPI с помощью ImageMagick без изменения фактического размера байта данных изображения

45

В GIMP есть очень простой способ делать то, что я хочу. У меня установлен только немецкий диалог, но я постараюсь перевести его. Я говорю о поездке , Picture -> PrintingSizeа затем регулируя значения X-Resolutionи Y-Resolutionкоторые мне известно , как так называемых значения DPI. Вы также можете выбрать формат, который по умолчанию Pixel/Inch. (На немецком диалог есть Bild -> Druckgrößeи там X-Auflösungи Y-Auflösung)

Хорошо, значения там часто 72по умолчанию. Когда я изменяю их, например, 300это приводит к тому, что изображение остается неизменным на компьютере, но если я его распечатываю, оно будет меньше, если вы посмотрите на него, но все детали все еще там, только меньше -> оно имеет более высокое разрешение на печатной бумаге (но меньшего размера ... что мне подходит).

Я часто делаю это, когда я работаю с LaTeX, или, если быть точным, с командой pdflatexна недавней Ubuntu-Machine. Когда я делаю вышеупомянутый процесс с 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.

Борис Деппен
источник
user1694803: Вы должны помнить, чтобы вернуться к ответу Мартина Уилсона и тоже «поставить голос» (нажать на маленькую ^иконку слева от его ответа), а не просто «принять» его, как только у вас будет достаточно личной репутации (я думаю, что вам нужно) +15) ...
Курт Пфайфл

Ответы:

76

Укажите единицы измерения - мне кажется, что у меня возникла проблема, когда я пропустил эту опцию (хотя DPI должен быть по умолчанию), например:

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

Знаете ли вы, какие встроенные поля данных используются GIMP для считывания разрешения - есть ли у него собственные, которые перекрывают стандартные, используемые ImageMagick? Например, Photoshop использует, Photoshop:XResolutionи Photoshop:YResolutionпоэтому вы должны установить их для Photoshop, чтобы распознавать настройку плотности (ImageMagick не может этого сделать - мы используем ExifTool).

Мартин Уилсон
источник
2
Мне нужно было поставить -density 300раньше input.png. Я конвертировал PDF-файлы. Спасибо, в любом случае.
Акостадинов
Для преобразования PNG в TIFF мне нужно было использовать -set units PixelsPerInch -density 300, простой -unitsне работал независимо от порядка опций.
Андрей
5

Обратите внимание, что вы можете использовать Exiftool для считывания резолюций. Например, Exiftool '-*resolution*' c.jpgможет показать

Блок разрешения: дюймы X Разрешение: 300 Y Разрешение: 300

Exiftool также может устанавливать параметры, но, как отмечено на man-странице Image::ExifTool::TagNames, дополнительные теги XResolution и YResolution недоступны для записи Exiftool.

Я не знаю, есть ли у 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;
}
Джеймс Уолдби - jwpat7
источник
1
Это мне не очень помогает, так как я имею дело с PNG и не очень разбираюсь в JPG или даже в C. Это значит, что для меня "глубокие" знания полезны. Может быть, кто-то еще может использовать это.
Борис Деппен
Да, я должен был уделить больше внимания этому вопросу! Перечитывая это, JPG не упоминается, PNG явно есть.
Джеймс Уолдби - jwpat7
Да, я кто-то другой, и я могу его использовать: я открыл свой файл .jpg в шестнадцатеричном редакторе и отредактировал девятый и одиннадцатый байт для вертикальной и горизонтальной плотности. Так сказать, я «выполнил» ваш код вручную.
u_Ltd.
2

Я не мог понять, как убедить преобразовать, чтобы только добавить метаданные, а не перекодировать мое [монохромное] растровое изображение; это было расширение файла> 50%.

Я обнаружил, что pngcrush (не инструмент ImageMagick) также может добавлять метаданные плотности. Эта командная строка помечает его как 600dpi и позволяет другие оптимизации, которые уменьшили размер файла на ~ 10%:

pngcrush -res 600 in.png out.png
Чарльз Болинг
источник
-1

«Я хочу изменить DPI с помощью Imagemagick без изменения фактического размера байта данных изображения».

Это абсолютно невозможно!

Потому что:

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

Также вы не понимаете, что такое DPI в реальности:

  1. Это абсолютно абстрактное значение, которое приобретает практическую ценность только в контексте знания также абсолютного размера распечатки или рендеринга на экране или мониторе:
    • Вы можете «напечатать» то же самое изображение 72x72 пикселей на квадрате шириной 1 дюйм: распечатка будет иметь разрешение 72dpi.
    • Вы также можете «напечатать» его на квадрате шириной 1/4 дюйма: тогда распечатка будет иметь разрешение 288dpi.
    • ( Примечание: если вы «напечатаете» его на 288dpi1-дюймовом квадрате, оно больше не будет тем же изображением: оно будет подвергнуто некоторой экстраполяции через драйвер принтера или какой-либо другой механизм фильтрации, и вместо изображения оно станет изображением размером 288x288 пикселей. 72x72 пикселей изображения ... )
  2. Обе распечатки будут иметь одинаковую информацию об изображении - изображение с разрешением 288 точек на дюйм не будет внезапно иметь больше.

Если вы хотите напечатать исходное изображение размером 72x72 пикселей в виде квадрата шириной 1 дюйм, но при этом 288dpiвам придется изменить масштаб изображения (в данном случае его масштабировать). Для каждого 1 пикселя в оригинале вам понадобится 4 пикселя нового увеличенного изображения. Теперь есть разные алгоритмы, которые можно использовать для вычисления значений цвета, которые должны иметь эти 4 пикселя (из них 3 новых пикселя):

  • вы могли бы дать им так же, как исходный пиксель (который является очень «сырым» алгоритм,
  • или вы могли бы сделать некоторое усреднение значения цвета исходного пикселя со значениями цвета соседних пикселей.

В любом случае вы создаете увеличенное изображение, состоящее из 288 строк пикселей, каждая из которых имеет высоту 288 пикселей (288x288 пикселей).

Что Gimp делает для вас, когда вы проходите через «Picture -> Printing Size»: он упрощает процесс пересчета необходимых изменений в абсолютных размерах пикселей, делая его более удобным для пользователя. Для этого ...

  • ... сначала он спрашивает о DPI, поскольку данный принтер не может произвольно изменить разрешение печати (некоторые могут предлагать не одно, а, возможно, даже 2 или 3 разных разрешения). Таким образом, он спрашивает вас, в каком разрешении вы хотите распечатать. Это первая информация.
  • ... то она просит вторую часть информации: на какой размер (в cm, mmили inch) распечатка должна появиться на бумаге.

В соответствии с этими двумя частями информации Gimp затем вычисляет общее количество пикселей, которое он должен использовать (экстраполировать из исходного числа пикселей), чтобы заполнить запрошенное пространство с запрошенным разрешением.

Однако увеличение растрового изображения за счет увеличения количества пикселей не добавляет к нему реальной информации, а только добавляет к нему «качество», которое является вымышленным. Человеческому глазу может показаться приятнее, если ваш алгоритм масштабирования будет «хорошим». И это будет выглядеть ужасно, если вы просто удвоите, утроите или увеличите в четыре раза существующие пиксели, как это делают некоторые простые алгоритмы.

Для растровых изображений
настройка DPI имеет значение только в контексте печати или отображения . Поскольку принтеры или мониторы дали, фиксированные разрешения. Поэтому только информация ...

  • ... драйвер принтера или
  • ... приложение для обработки изображений, которое поддерживает печать

нужно знать.

И документация ImageMagick полностью согласна со мной:

-density width
-density widthxheight
Установите горизонтальное и вертикальное разрешение изображения для отображения на устройствах.

Однако для векторных изображений или форматов файлов
(таких как PDF или PostScript) настройка DPI чрезвычайно важна в контексте их растеризации . Более высокое DPI будет передавать больше информации об изображении в растровый формат и, следовательно, сохранять больше деталей с реальным оригинальным качеством. При преобразовании векторного изображения заданного размера вmm,cmилиinchв растру с более высоким DPI будет непосредственно перевести в более высокое число общих пикселей в изображении.

Кроме того, ImageMagick не поддерживает «печать» как таковую. Вместо этого только ImageMagick ...

  • ... конвертирует файлы из указанного растрового формата в другие растровые форматы;
  • ... или уменьшает или увеличивает растровые изображения;
  • ... или изменяет значения цвета в соответствии с определенным алгоритмом;
  • ... или обрезает изображения, накладывает их, инвертирует, отражает их;
  • ...и что "нет....

... но для печати манипулируемых изображений вам нужно использовать другую программу.

Некоторые форматы изображений (TIFF, PNG, ...) поддерживают внутреннее хранение настроек DPI в своих метаданных.

Но это не более чем атрибут «подсказка», который не изменяет базовое растровое изображение. Вот причина, почему вы сделали это открытие:

«Когда я проверяю файл, он остается прежним».

Эта «подсказка» может быть автоматически оценена драйверами принтера или программами создания страниц, такими как LaTeX. В отсутствие таких «подсказок» DPI (или если они каким-то образом не представляют себя так, как ожидает от них LaTeX), LaTeX по-прежнему должен иметь возможность отображать любое изображение на странице так, как этого ожидают. чтобы - ему нужен только более явный код LaTeX вокруг изображения!

Некоторые другие форматы изображений (JPEG (?), BMP, ...) даже не поддерживают хранение подсказок DPI для своих внутренних метаданных.

Так что Gimp поддерживает только то, что вы видите, что он делает с «Picture -> Printing Size», потому что он хочет напечатать изображение. С ImageMagick вы не можете печатать.

Продолжайте делать то, что вы хотите делать с Gimp, когда вы печатаете. Это не имеет смысла с ImageMagick.

Смотрите также этот дополнительный фрагмент документации по IM , который объясняет одну и ту же тему разными словами.


Итак, что остается, это:

  • Если вы «манипулируете» своим изображением с помощью Gimp, а затем вставляете результат в LaTeX, страница выглядит так, как вы ожидаете.
  • Если вы «манипулируете» своим изображением с помощью ImageMagick, а затем вставляете результат в LaTeX, страница выглядит не так, как вы ожидаете.

Пожалуйста, предоставьте следующую информацию для решения вышеуказанной проблемы:

  • точная версия вашей установки ImageMagick (полный вывод convert -versionи convert -list configure);
  • (ссылка на) оригинальный образец изображения;
  • (ссылка на) то же изображение, управляемое Gimp;
  • (ссылка на) то же изображение, управляемое ImageMagick.

Таким образом, мы можем помочь решить проблему.

Но обратите внимание: это проблема, отличная от той, которая задается вашей текущей темой / заголовком: «Я хочу изменить DPI с помощью Imagemagick без изменения фактического размера байта данных изображения»


Обновить

Поскольку некоторым читателям все еще не ясно, что я отметил выше, вот еще одна попытка ...

Все, что отмечено как «Разрешение» или «Плотность» внутри файла изображения, является атрибутом метаданных . Он не влияет на количество реальных пикселей, описываемых файлом, и совершенно не имеет значения в этом отношении. Это просто подсказка, которой может или не может следовать устройство печати или рендеринга или приложение при печати, рендеринге или отображении изображения.

Для этого в файле изображения хранится всего несколько цифр. Эти числа показывают устройства вывода, такие как принтеры, и показывают, сколько точек (или пикселей) на дюйм должно отображаться на изображении. Для векторных форматов, таких как PostScript, PDF, MWF и SVG, указывается масштаб в пикселях для отрисовки любых реальных координат, используемых изображением.

Одним из примеров, в котором значение разрешения, отмеченное ImageMagick внутри метаданных изображения, НЕ учитывается приложением, является Adobe Photoshop. Photoshop хранит свои подсказки о желаемом разрешении печати или дисплея в собственном профиле с именем 8bim . ImageMagick не касается этого профиля, даже когда его просят записать изменение разрешения в метаданные файла изображения. Фотошоп, с другой стороны, будет игнорировать все подсказки разрешения, сохраненные ImageMagick в стандартном поле метаданных, которое определено для этой цели, как только оно увидит свой собственный профиль 8bim .

ФП должен был выбрать заголовок:

  • «Я хочу изменить DPI (подсказку о разрешении метаданных) с помощью ImageMagick без изменения фактического количества пикселей в изображении»

во избежание недоразумений ...

Курт Пфайфл
источник
1
«Когда я проверяю файл, он остается прежним». ЭТО ТО, ЧТО Я ХОЧУ. Я не говорю в тексте, что это удивляет меня. ПОЖАЛУЙСТА, ПРОЧИТАЙТЕ МОЙ ВОПРОС СНОВА ... МЕДЛЕННО ... АРГЛ
Борис Деппен
6
"Это совершенно невозможно!" Нет, это возможно ... просто изображение уменьшается при печати. Что я очень подробно объяснил в своем вопросе
Борис Деппен,
5
О чем ты вообще говоришь? Я подробно объяснил свой вариант использования внутри вопроса. Если вы отвечаете на вопросы только по названию, вы никому здесь не поможете.
Борис Деппен
4
Ваш фатальный недостаток был исходным предположением: «больше пикселей на область <==> больше общих пикселей на изображение». Это верно только в том случае, если область постоянна. Это не вариант.
Лев Изен
1
Да. DPI имеет смысл только если отображается на устройствах. Это также может быть поле, которое может быть сохранено в файле изображения, когда это разрешение имеет значение. На вопрос четко задан вопрос, как изменить это поле без изменения данных пикселей.
Лев Изен