Я хочу змінити 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, як я можу прочитати всюди в Інтернеті. Здається, працює. Але коли я перевіряю файл, він залишається таким же (EDIT: що я очікую, як пояснено вище).

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, 72замість нього встановлюються значення DPI 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 також може встановлювати параметри, але як зазначається на сторінці людини 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;
}

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.
    • ( Примітка. Якщо ви «роздрукуєте» його 288dpiна 1-дюймовому квадраті, це вже не те саме зображення: воно зазнало б деяку екстраполяцію через драйвер принтера чи якийсь інший механізм фільтрації, і воно стане зображенням 288x288 пікселів замість зображення 72x72 пікселів ... )
  2. Обидва роздруківки матимуть однакову інформацію про зображення - зображення 288dpi несподівано матиме більше.

Якщо ви хочете роздрукувати оригінальне зображення розміром 72x72 пікселів 288dpiу розмірі 1 дюймового квадрата, але в такому випадку, вам доведеться змінити масштаб зображення (у цьому випадку масштабування його). На кожні 1 пікселя в оригіналі вам знадобиться 4 пікселі нового масштабного зображення. Зараз існують різні алгоритми, за допомогою яких можна обчислити, які значення кольорів повинні мати ці 4 пікселі (3 з них нові пікселі):

  • ви можете дати їм те саме, що і вихідний піксель (що є дуже "необробленим" алгоритмом,
  • або ви можете виконати усереднення вихідного значення кольору пікселя із значеннями кольорів сусідніх пікселів.

У будь-якому випадку ви створюєте велике зображення, що складається з 288 рядків пікселів, кожен з яких має висоту 288 пікселів (288x288 пікселів).

Що Gimp робить для вас, коли ви переходите через "Зображення -> Розмір друку": це спрощує процес перерахунку необхідних змін в абсолютних розмірах пікселів, роблячи його більш зручним для користувачів. Для цієї мети...

  • ... він спочатку запитує вас про 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 підтримує лише те, що, як ви бачите, робить із "Зображення -> Розмір друку", оскільки він хоче надрукувати зображення. З ImageMagick ви не можете друкувати.

Продовжуйте робити те, що ви хочете робити з Gimp під час друку. З ImageMagick це не має сенсу.

Дивіться також цей додатковий фрагмент документації щодо чату , який пояснює ту саму тему різними словами.


Отже, що залишається, це:

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

Будь ласка, вкажіть наступне, щоб вирішити вказане вище питання:

  • точну версію установки ImageMagick (повний вихід convert -versionта convert -list configure);
  • (посилання на) вихідне зразкове зображення;
  • (посилання на) те саме зображення, яке маніпулює Gimp;
  • (посилання на) те саме зображення, яке маніпулює ImageMagick.

Таким чином ми можемо допомогти вирішити проблему.

Але зауважте: це інша проблема, ніж запитання вашого поточного предмета / заголовка: "Я хочу змінити DPI на Imagemagick без зміни фактичного розміру байтів даних зображення"


Оновлення

Оскільки деяким читачам досі не зрозуміло, що я зазначив вище, ось ще одна спроба ...

Те, що зазначається як "Роздільна здатність" або "Щільність" у файлі зображення, є атрибутом метаданих . Це не впливає на кількість фактичних пікселів, описаних файлом, і в цьому відношенні абсолютно не має значення. Це лише натяк, до якого друкований або рендерируючий пристрій чи додаток можуть або не дотримуватися під час друку, надання чи відображення зображення.

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

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

ОП має обрати заголовок:

  • "Я хочу змінити DPI (натяк на роздільну здатність метаданих) на ImageMagick, не змінюючи фактичну кількість пікселів на зображенні"

щоб уникнути всіх непорозумінь ...


1
"Коли я перевіряю файл, він залишається таким же." ЦЕ Я ХОЧУ. Я НЕ СКАЖУТЬ В ТЕКСТІ, ЩО ЦЕ НАДАЄ МЕНЕ. БУДЬТЕ ЧИТАЙТЕ МОЕ ЗАПИТАННЯ ... МАЛКО ... АРГЛ
Борис Даппен

6
"Це абсолютно неможливо!" Ні, це неможливо ... просто зображення зменшується при друкуванні. Що я дуже детально пояснив у своєму питанні
Борис Даппен,

5
Про що ти навіть говориш. Я детально пояснив свій приклад використання всередині питання. Якщо ви відповідаєте на питання лише за назвою, ви нікому тут не допомагаєте.
Борис Даппен

4
Вашим фатальним недоліком було початкове припущення: "більше пікселів на площу <==> більше загальних пікселів на зображення" Це справедливо лише в тому випадку, якщо область є постійною. Це не так.
Лев Ізен

1
Так. DPI має сенс лише в тому випадку, якщо він надається пристроям. Також трапляється поле, яке може зберігатися у файлі зображень, коли ця резолюція є актуальною. У запитанні чітко було задано, як змінити це поле без зміни піксельних даних.
Лев Ізен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.