Chcę zmienić DPI za pomocą ImageMagick bez zmiany rzeczywistego rozmiaru bajtów danych obrazu

45

W GIMP jest bardzo prosty sposób na robienie tego, co chcę. Mam tylko zainstalowany niemiecki dialog, ale spróbuję go przetłumaczyć. Mówię o zamiar Picture -> PrintingSize, a następnie dostosowanie wartości X-Resolutioni Y-Resolutionktóre są mi znane jako tzw wartości DPI. Możesz także wybrać format domyślnie Pixel/Inch. (W języku niemieckim okno dialogowe jest Bild -> Druckgrößei tam X-Auflösungi Y-Auflösung)

Ok, wartości są często 72domyślnie. Kiedy zmienię je na np 300. Spowoduje to, że obraz pozostanie taki sam na komputerze, ale jeśli go wydrukuję, będzie mniejszy, jeśli na niego spojrzysz, ale wszystkie szczegóły nadal tam są, tylko mniejsze -> ma wyższa rozdzielczość na drukowanym papierze (ale mniejszy rozmiar ... co jest dla mnie w porządku).

Często robię to, kiedy pracuję z LaTeX, lub mówiąc dokładnie z poleceniem pdflatexna najnowszej maszynie Ubuntu. Kiedy wykonuję powyższy proces za pomocą GIMP ręcznie, wszystko działa dobrze. Obrazy będą wyświetlane w wynikowym pliku PDF, ale będą miały wysoką jakość drukowania.

Staram się zautomatyzować proces przechodzenia do GIMP i dostosowywania wartości DPI. Ponieważ ImageMagick jest znany z doskonałości i wykorzystałem go do wielu innych zadań, starałem się osiągnąć swój cel za pomocą tego narzędzia. Ale po prostu nie robi tego, co chcę.

Po wypróbowaniu wielu rzeczy, wydaje mi się, że tak naprawdę to polecenie powinno być moim przyjacielem:

convert input.png -density 300 output.png

To powinno ustawić DPI na 300, ponieważ mogę czytać wszędzie w sieci. Wydaje się, że działa. Ale kiedy sprawdzam plik, pozostaje ten sam (EDYCJA: tego się spodziewam, jak wyjaśniono powyżej).

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

Kiedy używam tego polecenia, wydaje się, że zrobił to, co chciałem:

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

Zabawne, to samo wyjście, input.pngco mnie dezorientuje ... więc może to być złe parametry do oglądania?

Ale kiedy teraz renderuję mój TeX z pdflatexobrazem jest nadal duży i rozmazany. Również gdy ponownie otworzę obraz za pomocą GIMP, wartości DPI są ustawione na 72zamiast 300. Więc właściwie nie było żadnego efektu.

Na czym polega problem. Czy dostaję coś zupełnie nie tak? Nie mogę się mylić, ponieważ wszystko działa dobrze z GIMP.

Dzięki za wszelką pomoc w tym. Jestem również otwarty na inne zautomatyzowane rozwiązania, które można łatwo wykonać w systemie Linux.

Boris Däppen
źródło
user1694803: Powinieneś pamiętać o powrocie do odpowiedzi Martina Wilsona i jej „głosowaniu” (kliknij małą ^ikonę po lewej stronie jego odpowiedzi), a nie tylko „zaakceptowaniu”, gdy tylko będziesz mieć wystarczającą osobistą reputację (myślę, że potrzebujesz +15) ...
Kurt Pfeifle

Odpowiedzi:

76

Podaj jednostki - wydaje mi się, że mam problem z pominięciem tej opcji (chociaż DPI powinien być domyślny), na przykład:

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

Czy wiesz, które osadzone pola danych wykorzystuje GIMP do odczytu rozdzielczości - czy ma własne, które zastępują standardowe pola używane przez ImageMagick? Na przykład, Photoshop zastosowania Photoshop:XResolutioni Photoshop:YResolutiontak trzeba ustawić je dla Photoshop rozpoznać ustawienie gęstości (ImageMagick nie może tego zrobić - używamy ExifTool).

Martin Wilson
źródło
2
Musiałem postawić -density 300przed input.png. Konwertowałem pliki PDF. W każdym razie dzięki.
akostadinov
Do konwersji PNG na TIFF, której potrzebowałem -set units PixelsPerInch -density 300, prosty -unitsnie działał bez względu na kolejność opcji.
Andrey
5

Pamiętaj, że możesz używać Exiftool do odczytywania rozdzielczości. Na przykład Exiftool '-*resolution*' c.jpgmoże pokazać

Rozdzielczość: cale X Rozdzielczość: 300 Y Rozdzielczość: 300

Exiftool może również ustawiać parametry, ale jak zauważono na stronie Image::ExifTool::TagNamespodręcznika, dodatkowe tagi XResolution i YResolution nie są zapisywane przez Exiftool.

Nie wiem, czy ImageMagick ma opcje zmiany rozdzielczości, ale byłbym zaskoczony, gdyby tak nie było. Łatwo jest także pisać skrypty GIMP w celu automatyzacji takich zadań, a także można zmieniać rozdzielczości za pomocą małych programów. Na przykład poniżej znajduje się program C (kompilowany przez gcc setRes.c -O3 -Wall -o setRes), który czyta pierwsze kilka bajtów pliku jpeg, zmienia rozdzielczości na 300 i przepisuje je. Przedstawiony program używa stałych dla maszyn little-endian, takich jak x86. Jeśli działa na maszynie typu big-endian, powinien zakończyć się komunikatem typu Error: xyz may be not a .jpg file, nawet jeśli xyz jest plikiem jpeg. Uwaga: nie testowałem uzyskanych zdjęć za pośrednictwem pdflatex; prawdopodobnie warto zadać pytanie w 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;
}
James Waldby - jwpat7
źródło
1
Nie bardzo mi to pomaga, ponieważ mam do czynienia z PNG i nie mam pojęcia o JPG, a nawet C. To jest „głęboka” wiedza, aby być użytecznym. Może ktoś inny może z niego skorzystać.
Boris Däppen,
Tak, powinienem był zwrócić większą uwagę na to pytanie! Powtarzając to, JPG nie jest wspomniane, PNG najwyraźniej jest.
James Waldby - jwpat7
Tak, jestem kimś innym i można go używać: Ja otworzyłem plik .jpg w edytorze hex i edytowane dziewiąty i jedenasty bajt dla gęstości pionowej i poziomej. So-to-speak „wykonałem” Twój kod ręcznie.
u_Ltd.
2

Nie mogłem wymyślić, jak przekonać konwersję, aby dodała tylko metadane i nie ponownie kodowała mojej [monochromatycznej] mapy bitowej; rozwijał plik> 50%.

Odkryłem, że pngcrush (nie narzędzie ImageMagick) może również dodawać metadane gęstości. Ten wiersz polecenia oznacza 600dpi i pozwala na inne optymalizacje, które zmniejszyły rozmiar pliku o ~ 10%:

pngcrush -res 600 in.png out.png
Charles Boling
źródło
-1

„Chcę zmienić DPI za pomocą Imagemagick bez zmiany rzeczywistego rozmiaru bajtów danych obrazu”.

To jest całkowicie niemożliwe!

Dlatego:

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

Wydaje się również, że nie rozumiesz, czym w rzeczywistości jest DPI:

  1. Jest to całkowicie abstrakcyjna wartość, która zyskuje praktyczną wartość tylko w kontekście znajomości bezwzględnego rozmiaru wydruku lub renderowania na ekranie lub monitorze:
    • Możesz „wydrukować” ten sam obraz 72x72 pikseli na kwadracie o szerokości 1 cala: wydruk będzie miał rozdzielczość 72dpi.
    • Możesz go również „wydrukować” na kwadracie o szerokości 1/4 cala: wtedy wydruk będzie miał rozdzielczość 288dpi.
    • ( Uwaga: jeśli „wydrukujesz” go na 288dpikwadracie o przekątnej 1 cala, nie będzie to już ten sam obraz: zostanie on poddany ekstrapolacji przez sterownik drukarki lub inny mechanizm filtrujący, a zamiast tego będzie miał obraz 288 x 288 pikseli obraz 72x72 pikseli ... )
  2. Oba wydruki będą miały te same informacje o obrazie - obraz o rozdzielczości 288 dpi nie będzie nagle miał więcej.

Jeśli chcesz wydrukować oryginalny obraz 72 x 72 piksele jako kwadrat o szerokości 1 cala, ale w 288dpi, wtedy musisz przeskalować obraz (w tym przypadku skalować go w górę). Na każdy 1 piksel w oryginale potrzebujesz 4 pikseli nowego, powiększonego obrazu. Teraz istnieją różne algorytmy, których można użyć do obliczenia, jakie wartości kolorów powinny mieć te 4 piksele (3 z nich nowe piksele):

  • możesz dać im to samo, co oryginalny piksel (który jest bardzo „surowym” algorytmem,
  • lub możesz zrobić uśrednienie wartości koloru oryginalnego piksela z wartościami kolorów sąsiednich pikseli.

W każdym razie tworzysz większy obraz składający się z 288 rzędów pikseli o wysokości 288 pikseli (288 x 288 pikseli).

Co robi dla ciebie Gimp po przejściu przez „Obraz -> Rozmiar wydruku”: upraszcza proces ponownego obliczania wymaganych zmian w absolutnych rozmiarach pikseli, czyniąc go bardziej przyjaznym dla użytkownika. W tym celu ...

  • ... najpierw pyta o DPI, ponieważ dana drukarka nie może arbitralnie zmienić rozdzielczości drukowania (niektóre mogą zaoferować nie tylko jedną, ale może nawet 2 lub 3 różne rozdzielczości). Pyta więc, w jakiej rozdzielczości chcesz wydrukować. To jest pierwsza informacja.
  • ... to zwraca się również do drugiego kawałka informacji: w którym wielkość (w cm, mmlub inch) wydruk powinien pojawić się na papierze.

Zgodnie z tymi dwoma informacjami Gimp oblicza całkowitą liczbę pikseli, których musi użyć (ekstrapolować z pierwotnej liczby pikseli), aby wypełnić żądane miejsce w żądanej rozdzielczości.

Jednak skalowanie obrazu rastrowego poprzez dodanie większej liczby pikseli nie dodaje do niego prawdziwych informacji, a jedynie dodaje „jakości”, która jest fikcyjna. Dla ludzkiego oka może to wyglądać ładniej, jeśli algorytm zwiększania skali jest „dobry”. I będzie wyglądać brzydko, jeśli podwoisz, potroisz lub poczwórnie istniejące piksele, tak jak robią to niektóre proste algorytmy.

W przypadku obrazów rastrowych
ustawienie DPI ma znaczenie tylko w kontekście drukowania lub wyświetlania . Ponieważ drukarki lub monitory mają ustalone rozdzielczości. Dlatego jest to informacja, że ​​tylko ...

  • ... sterownik drukarki lub
  • ... aplikacja do przetwarzania obrazu obsługująca drukowanie

potrzebuję wiedzieć.

A dokumentacja ImageMagick jest w pełni zgodna ze mną:

-density width
-density widthxheight
Ustaw poziomą i pionową rozdzielczość obrazu do renderowania na urządzeniach.

W przypadku obrazów wektorowych lub formatów plików
(takich jak PDF lub PostScript) ustawienie DPI jest jednak niezwykle ważne w kontekścieich rasteryzacji . Wyższe DPI przeniesie więcej informacji o obrazie do formatu rastrowego, a tym samym zachowa więcej szczegółów z prawdziwej oryginalnej jakości. Podczas przekształcania obrazu wektora w danej wielkościmm,cmlubinchw rastrze o wyższym DPI będzie bezpośrednio przekłada się na wyższą całkowitej liczby pikseli w obrazie.

Ponadto ImageMagick nie obsługuje „drukowania” jako takiego. Zamiast tego tylko ImageMagick ...

  • ... konwertuje pliki z danego formatu rastrowego na inne formaty rastrowe;
  • ... lub zmniejsza lub rastruje obrazy;
  • ... lub zmienia wartości kolorów zgodnie z określonym algorytmem;
  • ... lub przycina obrazy, nakłada je, odwraca, odzwierciedla je;
  • ... a co nie ....

... ale aby wydrukować zmanipulowane obrazy, musisz użyć innego programu.

Niektóre formaty obrazu (TIFF, PNG, ...) obsługują zapisywanie ustawienia DPI wewnętrznie w swoich metadanych.

Ale to tylko atrybut „podpowiedzi”, który nie zmienia podstawowego obrazu rastrowego. Właśnie dlatego dokonałeś tego odkrycia:

„Kiedy sprawdzam plik, pozostaje ten sam”.

Ta „wskazówka” może być automatycznie oceniona przez sterowniki drukarki lub programy do tworzenia stron, takie jak LaTeX. W przypadku braku takich „wskazówek” DPI (lub jeśli w jakiś sposób nie prezentują się w sposób, w jaki LaTeX tego oczekuje), LaTeX nadal powinien mieć możliwość wyświetlenia dowolnego obrazu na stronie tak, jak się tego spodziewasz do - potrzebuje tylko bardziej wyraźnego kodu LaTeX wokół obrazu!

Niektóre inne formaty obrazu (JPEG (?), BMP, ...) nawet nie obsługują przechowywania podpowiedzi DPI na ich wewnętrznych metadanych.

Tak więc Gimp obsługuje tylko to, co widzisz dzięki opcji „Obraz -> Rozmiar wydruku”, ponieważ chce wydrukować obraz. Dzięki ImageMagick nie można drukować.

Podczas drukowania rób to, co chcesz robić z Gimpem. Z ImageMagick nie ma to sensu.

Zobacz także ten dodatkowy fragment dokumentacji czatu , który wyjaśnia ten sam temat innymi słowami.


Pozostaje więc:

  • Jeśli „zmanipulujesz” swój obraz za pomocą Gimp, a następnie osadzisz wynik w LaTeX, strona wygląda tak, jakbyś tego oczekiwał.
  • Jeśli „zmanipulujesz” swój obraz za pomocą ImageMagick, a następnie osadzisz wynik w LaTeX, strona wygląda inaczej niż się spodziewasz.

Podaj następujące informacje, aby rozwiązać powyższy problem:

  • dokładna wersja twojej instalacji ImageMagick (pełne wyjście convert -versioni convert -list configure);
  • (link do) oryginalnego przykładowego obrazu;
  • (link do tego) ten sam obraz, którym manipulował Gimp;
  • (link do tego samego obrazu manipulowanego przez ImageMagick.

W ten sposób możemy pomóc rozwiązać problem.

Ale uwaga: jest to inny problem niż ten, o który pyta twój obecny temat / nagłówek: „Chcę zmienić DPI za pomocą Imagemagick bez zmiany rzeczywistego rozmiaru bajtów danych obrazu”


Aktualizacja

Ponieważ niektórym czytelnikom wciąż nie jest jasne, co zauważyłem powyżej, oto jeszcze jedna próba ...

Cokolwiek jest oznaczone jako „Rozdzielczość” lub „Gęstość” w pliku obrazu, jest atrybutem metadanych . Nie ma to wpływu na liczbę rzeczywistych pikseli opisanych w pliku i jest całkowicie nieistotne w tym względzie. Jest to tylko wskazówka, której urządzenie drukujące lub renderujące lub aplikacja może, ale nie musi, stosować podczas drukowania, renderowania lub wyświetlania obrazu.

W tym celu jest to tylko niewielka liczba przechowywana w pliku obrazu. Liczby te informują urządzenia wyjściowe, takie jak drukarki, i wyświetlają liczbę punktów (lub pikseli) na cal, na których obraz powinien być wyświetlany. W przypadku formatów wektorowych, takich jak PostScript, PDF, MWF i SVG, informuje skalę pikseli, aby narysowała dowolne współrzędne świata rzeczywistego używane przez obraz.

Jednym z przykładów, w którym wartość rozdzielczości odnotowana przez ImageMagick wewnątrz metadanych obrazu NIE jest honorowana przez aplikację, jest Adobe Photoshop. Photoshop przechowuje wskazówki dotyczące pożądanej rozdzielczości wydruku lub wyświetlania w zastrzeżonym profilu o nazwie 8bim . ImageMagick nie dotyka tego profilu, nawet gdy zostanie poproszony o zapisanie zmiany rozdzielczości w metadanych pliku obrazu. Z drugiej strony Photoshop zignoruje wszystkie wskazówki dotyczące rozdzielczości przechowywane przez ImageMagick w standardowym polu metadanych zdefiniowanym w tym celu, gdy tylko zobaczy swój własny profil 8bim .

PO powinien był wybrać nagłówek:

  • „Chcę zmienić DPI (wskazówkę dotyczącą rozdzielczości metadanych) za pomocą ImageMagick bez zmiany faktycznej liczby pikseli na obrazie”

aby uniknąć wszelkich nieporozumień ...

Kurt Pfeifle
źródło
1
„Kiedy sprawdzam plik, pozostaje ten sam”. TO JEST TO CZEGO CHCĘ. Nie mówię w tekście, który mnie zaskakuje. PROSZĘ PRZECZYTAĆ PONOWNIE MOJE PYTANIE ... POWOLNIE ... ARGL
Boris Däppen
6
„To jest całkowicie niemożliwe!” Nie, to możliwe ... po prostu obraz kurczy się po wydrukowaniu. Które wyjaśniłem bardzo szczegółowo w moim pytaniu
Boris Däppen,
5
O czym ty w ogóle mówisz. Wyjaśniłem szczegółowo mój przypadek użycia w pytaniu. Jeśli odpowiadasz na pytania tylko tytułem, nie jesteś tutaj nikomu pomocny.
Boris Däppen
4
Twoja fatalna wada była początkowym założeniem: „więcej pikseli na obszar <==> więcej wszystkich pikseli na obraz” To prawda, tylko jeśli obszar jest stały. Nie o to chodzi.
Leo Izen
1
Tak. DPI ma znaczenie tylko w przypadku renderowania na urządzeniach. Zdarza się również, że jest to pole, które można zapisać w pliku obrazu, gdy ta rozdzielczość jest istotna. Pytanie wyraźnie zadawało, jak zmienić to pole bez zmiany danych w pikselach.
Leo Izen