Jak mogę dodać ramkę do zdjęcia JPEG bez wpływu na jakość?

24

Mam zdjęcie w formacie JPEG o rozdzielczości 4680x3120. Chcę dodać białe obramowanie wokół tego zdjęcia, zmieniając je w zdjęcie 5200 x 3467 (z powodów drukowania).

Oczywiście nie zmieniam ani nie usuwam niczego ze zdjęcia, po prostu coś dodam. Dlatego w zasadzie procedura ta może być bezstratna. Jeśli jednak użyję programu Paint do dodania tej ramki, proces zapisywania programu Paint ponownie skompresuje zdjęcie do formatu JPEG, tracąc w ten sposób informacje i jakość.

Czy istnieje sposób (bardziej profesjonalny program), aby dodać coś do zdjęcia JPEG, na przykład ramkę, bez wpływu na oryginalną część zdjęcia, bez obniżania jego jakości?

LBogaardt
źródło

Odpowiedzi:

35

Chociaż odpowiedź Philipa jest najlepszym sposobem, możesz zrobić to, co chcesz, całkowicie w sferze JPEG.

JPEG działa poprzez dzielenie obrazu na bloki zwane minimalnymi jednostkami kodującymi (MCU), zwykle 16 × 16, i kompresowanie ich osobno. Można to zobaczyć na zdjęciach, gdy poziom kompresji jest bardzo wysoki. Przy bardziej rozsądnych poziomach kompresji bloki łączą się tak płynnie, że nigdy nie widać granic.

Możemy skorzystać z tego faktu, aby bezstratnie dodać prostą białą ramkę do obrazu. Po prostu musimy utworzyć pustą tablicę białych bloków równą wielkości obrazu wyjściowego, a następnie upuścić oryginalne bloki MCU JPEG na środek .¹

Ta technika ma wadę: działa tylko wtedy, gdy rozmiary obrazu wejściowego i wyjściowego są równe wielokrotności rozmiaru MCU. Jeśli tak nie jest, musimy ponownie skompresować niektóre bloki na marginesie między białą ramką a krawędziami oryginalnego obrazu. Nie zobaczysz tej różnicy na wyjściu, jeśli będziesz trzymał się z dala od nadmiernie wysokich poziomów kompresji JPEG, więc nadal jest skutecznie bezstratny.

Nie znam żadnego programu, który to robi. Najbliższą rzeczą, o której wiem, jest odwrotna operacja: jpegtran ma funkcję przycinania, która bezstratnie odcina części krawędzi obrazu .² Robi to, odrzucając przycięte MCU wzdłuż krawędzi obrazu, pozostawiając te w środkowy nietknięty.

Najprostszym gotowym rozwiązaniem, jakie znam, jest wtyczka Better JPEG Lossless Resave do Photoshopa. Wykorzystuje techniki oparte na podanych wyżej pomysłach, aby kopiować MCU z oryginalnego obrazu w dowolnym miejscu, aby uniknąć ich ponownego tworzenia z wersji nieskompresowanej, jak to zwykle robi Photoshop.


Dygresje:

  1. Możesz pomyśleć, że wynikowa ramka nie będzie całkiem biała , ponieważ utrata JPEG spowoduje pewną różnicę kolorów na wydruku. Zrobiłem kilka testów, a przynajmniej w Photoshopie, czysto biały obraz zapisany za pomocą JPEG 10 poziomu Save For Web (tzn. „Niskiej” jakości) daje zdekodowany obraz, który jest nadal czysto biały.

    Ustaliłem to za pomocą dwóch testów:

    Najpierw załadowałem plik JPEG jako warstwę na oryginał, ustawiłem tryb mieszania górnej warstwy na Różnica, a następnie dodałem warstwę dopasowania Poziomy nad nim, aby spróbować powiększyć różnice. Powstały obraz pozostał czarny, co oznacza „brak różnicy”.

    Po drugie, kiedy nie zauważyłem oczekiwanych różnic, upuściłem warstwę dopasowania i przywróciłem warstwę JPEG do trybu normalnego mieszania, podniosłem narzędzie kroplomierza i rozejrzałem się po obrazie pod kątem piksela, który nie był wyświetlany jako RGB (255,255,255 ) w panelu Informacje. Nigdy go nie znalazłem. Spodziewałem się, że liczby zaczną migotać trochę, gdy szorowałem obraz, ale pozostały stabilne.

    Mogę tylko stwierdzić, że jest to zdegenerowany przypadek algorytmu kodowania: czyste białe bloki pozostają białe przez dyskretną transformację kosinusową .

    Co ciekawe, nie dzieje się tak w przypadku czystych czarnych bloków. Przynajmniej z implementacją Photoshopa zmieniają się one w RGB (1,1,1) po zdekodowaniu, a nie RGB (0,0,0).

    Podsumowując, nie musisz się martwić o rozpylanie kropek w tym obszarze obramowania podczas drukowania obrazu wykonanego powyższą techniką.

  2. jpegtranjest programem wiersza poleceń, ale istnieje również program GUI dla systemu Windows oparty na tym samym kodzie o nazwie jpegcrop.

  3. Niestety, ta wtyczka jest przeznaczona tylko dla systemu Windows.

Warren Young
źródło
1
Użyłem programu o nazwie JPEG Wizard, który zapewniał taką funkcjonalność. Miał także bardzo dobrą zdolność do stosowania różnych współczynników kompresji do różnych części JPEG. Można zatem zastosować ustawienie wysokiej jakości dla głowy i dłoni danej osoby, średnią jakość ubrań i niższą jakość tła, a tym samym uzyskać mniejszy plik, ale lepszą ogólną jakość niż gdyby użyć średniej jakości do wszystkiego.
supercat
1
Nie miałem okazji tego wypróbować, ale ten post na blogu sugeruje, że jpegtranfunkcja przycinania może być również używana do rozszerzenia. (Nie jestem jednak pewien, jaki kolor będą miały przedłużone granice.)
mattdm,
4
@mattdm: Tak, jpegtranmożna również rozszerzyć obraz, ale zawsze zawiera on zakodowany na stałe środkowy szary kolor RGB (128, 128, 128). Robi to po prostu dlatego, że jest to jedyna łatwa opcja, ponieważ w przestrzeni o współczynniku DCT można to zrobić za pomocą prostego bzero()wywołania. Próbowałem dzikiego włamania do zmiany tego , co nie działa, ale powinno dać ci poczucie brzydoty. wznosi ręce w frustracji
Warren Young,
@WarrenYoung: Aby zmienić kolor bloków wypełnienia, prawdopodobnie musisz zmienić tylko pierwszy współczynnik (DC), a pozostałe pozostawić na zero. Oczywiście współczynniki są skompresowane, więc ... w każdym razie powinno to być wykonalne, ale zgadzam się, że nie jest tak banalne, jak mogłoby się wydawać.
Ilmari Karonen
2
Co do ostatniego punktu - największa oszczędność pochodzi z wyrzucania informacji o wysokiej częstotliwości. Zysk z rzucania precyzji na kolor jednolitego bloku pikseli nie może być większy niż bajt lub dwa, więc nigdy nie jest prawie nigdy. W przypadku utraty informacji następuje konwersja przestrzeni kolorów RGB YUV <-> RGB.
hobbs
20

Należy pamiętać, że podczas zapisywania zdjęcia w formacie stratnej kompresji tracisz jakość . Tak długo, jak zapiszesz zdjęcie w formacie bezstratnym (PSD, TIFF itp.) Po dodaniu ramki, nie stracisz więcej danych niż utraciłeś, zapisując zdjęcie jako JPEG.

Philip Kendall
źródło
1
Dzięki. I to prawda, nawet jeśli używasz „gównianego” programu, takiego jak Paint, kiedy zapisujesz go np. W TIFF?
LBogaardt,
4
Przynajmniej zgodnie z moim szybkim testem, Paint używa bezstratnego algorytmu kompresji LZW podczas zapisywania plików TIFF, dzięki czemu wygląda dobrze.
Philip Kendall,
5
Należy pamiętać, że może to znacznie zwiększyć rozmiar obrazu ...
BlueRaja - Danny Pflughoeft
2
farba obsługuje również format PNG, który jest również formatem bezstratnym
phuclv
+1 za to, ponieważ odpowiedzi omawiające zapisywanie z powrotem do formatu JPEG nie są kompatybilne ze wszystkimi opcjami kodowania JPEG.
James Snell,
6

Nie jest to dość bezstratne, ale możesz zbliżyć się za pomocą GIMP (lub innego edytora z podobną funkcją) i następujących dwóch sztuczek:

  1. Najpierw upewnij się, że dodawana ramka ma wielokrotność szerokości 8 pikseli (a najlepiej wielokrotność 16 pikseli).

    Jest to ważne, ponieważ algorytm kompresji JPEG dzieli obraz na bloki 8 × 8 pikseli *, zaczynając od lewego górnego rogu, i stosuje algorytm kompresji stratnej niezależnie do każdego bloku. Zatem przynajmniej w zasadzie można bezstratnie wypełniać obraz JPEG, dodając pełne bloki 8 x 8 pikseli wokół istniejących. Jeśli jednak spróbujesz dodać ramkę, która nie ma całej liczby bloków, bloki na wyściełanym obrazie nie będą się zgadzały z blokami w oryginale, a utrata kompresji byłaby nieunikniona.

    *) W rzeczywistości większość obrazów JPEG używa podpróbkowania barwy , co oznacza, że ​​tylko część obrazu w skali szarości jest faktycznie kompresowana w blokach 8 × 8, podczas gdy kanały barwy są zmniejszane o 50% przed kompresją, dzięki czemu ich efektywny rozmiar bloku wynosi 16 × 16 pikseli. Dlatego, aby uzyskać najlepsze wyniki, szerokość ramki powinna być naprawdę wielokrotnością 16 pikseli. Jednak zwykle można uniknąć obramowania 8 (lub 24 lub 40 itd.) Pikseli, ponieważ niewielka utrata kompresji w barwie nie jest bardzo zauważalna.

  2. Druga część triku polega na zaznaczeniu pola wyboru „Użyj ustawień jakości z oryginalnego obrazu” w oknie dialogowym Eksportuj obraz jako JPEG (w Ustawieniach zaawansowanych). Zrób to, nawet jeśli wydaje się, że spowoduje to obniżenie jakości niż zwykle!

    To ustawienie sprawia, że ​​GIMP ponownie używa dokładnie takich samych ustawień kompresji, jakie były stosowane w oryginalnym obrazie, co zwykle eliminuje około 99% strat kompresji, pod warunkiem, że nie edytowałeś obrazu zbyt mocno, a zwłaszcza, że ​​bloki w nowy obraz nadal jest zgodny z tymi w oryginale. (Czasami nadal będą występować pewne straty z powodu błędów zaokrągleń, ale znacznie mniej niż byłoby inaczej).


Aby szybko zademonstrować, wziąłem ten obraz testowy JPEG z Wikimedia Commons , pierwotnie zapisany z dość niską jakością 50, i dodałem do niego fantazyjną (w pewnym sensie) czarno-białą ramkę 8px, stosując metodę opisaną powyżej:

Obraz testowy z ramką 8px, w większości bezstratny

Oto różnica między oryginałem (15,1 kB) a edytowanym obrazem (16,7 kB), pokazanym przy użyciu trybu warstwowego „ekstrakcji ziarna” GIMP:

Różnica między wyściełanym obrazem a oryginałem

Możesz zobaczyć bardzo niewielkie błędy barwy, spowodowane tym, że szerokość ramki nie jest wielokrotnością 16, i (jeśli przyjrzysz się uważnie) kilka bloków, w których wystąpiły również niewielkie straty w kanale luma z powodu zaokrąglenia. Mimo to wizualnie oryginał i wypełniony obraz są prawie nie do odróżnienia, nawet przy dwukrotnym powiększeniu i na przemian między nimi.

W szczególności skontrastuj to z wynikiem podniesienia jakości JPEG z 50 do 60 przed zapisaniem wypełnionego obrazu, co daje następujący obraz 17,6 kB:

Obraz testowy z ramką 8px, jakość podniesiona z 50 do 60

Przy dużym powiększeniu zdecydowanie widać, że edytowany obraz jest wyraźnie rozmazany w niektórych miejscach niż oryginał, a różnica w ekstrakcie z ziarna potwierdza to:

Różnica między wyściełanym obrazem (przy q60) a oryginałem

Ilmari Karonen
źródło
„zaznaczenie tego pola wyboru nie wpływa na ustawienie„ Progresywne ”.” Nie jest to błąd, ponieważ kodowanie progresywne jest ustawieniem kodowania, a nie ustawieniem jakości. Jpegtran może bezstratnie konwertować obrazy do iz progresywnego.
Damian Yerrick
@tepples: Masz rację; Usunąłem ten akapit. Z jakiegoś powodu miałem wrażenie, że przełączanie trybu progresywnego spowoduje, że ustawienia jakości nie będą pasować, ale szybki test wydaje się potwierdzać, że się myliłem.
Ilmari Karonen,
1
@thomasrutter: Nie mogę przegłosować komentarza, więc po prostu wskażę oryginalny post na forum opisujący tę funkcję , a w szczególności ten cytat: „ Jeśli wprowadziłeś tylko kilka zmian w obrazie, to ponownie użycie tych samych tabel kwantyzacji zapewni prawie taką samą jakość, a rozmiar pliku to oryginalny obraz. Pozwoli to zminimalizować straty spowodowane krokiem kwantyzacji, w porównaniu do tego, co by się stało, gdyby zastosowano inne tabele kwantyzacji.
Ilmari Karonen
1
Dla porównania, oto kolejny przykład w odpowiedzi na inne pytanie. Moje rozumienie teoretyczne zgadza się z Ilmari, ale przynajmniej w moim przykładzie praktyka wydaje się być znacznie bardziej zgodna z tym, co mówi Thomas - przynajmniej gdy zaczyna się od bardzo zdegradowanego obrazu. (Myślę, że nagrobek jest kiepskim przykładem do tego celu, ponieważ utrata szczegółów na kamieniu jest mniej oczywista niż na ludzkiej skórze.)
mattdm,
1
@mattdm: Wydaje się, że jest całkowicie zależne od oprogramowania; Próbowałem odtworzyć twoje wyniki z tej odpowiedzi w GIMP i wydaje się, że GIMP (przynajmniej v2.8.10) jest znacznie lepszy w zachowaniu jakości JPEG niż ImageMagick (niezależnie od testowanej wersji). Twój pierwszy obraz, zapisany raz w q75, ma PSNR 34,0298, podczas gdy ten zapisany dwukrotnie w q75 ma jeden z 32,8169 (a ten zapisany 8 razy ma PSNR 32,6459). Dla porównania, zapisanie tego samego obrazu źródłowego raz w GIMP w q75 daje PSNR 36,4560; otwarcie i ponowne zapisanie tej samej jakości obniża go tylko nieznacznie, do 36,3295.
Ilmari Karonen
3

Przepraszam, jeśli nie jest to dokładnie to, czego chciałeś, ale ...

Wygląda na to, że dodajesz białą ramkę jako pomoc w ustawianiu obrazu podczas drukowania. Dlaczego nie skupić się na prawidłowym nauczeniu interfejsów drukowania i uniknąć takich podejrzanych hacków? Innym problemem, jaki się tu pojawia, jest to, że pozwalasz programowi drukującemu na zmianę rozmiaru obrazu 4680x3120 w celu dopasowania do prawidłowej DPI / rozdzielczości. Może to mieć poważniejszy efekt niż ponowne zapisanie pliku JPEG.

aaaaargZombies
źródło
Oba ważne punkty, dziękuję. Jednak przesłałem swoje zdjęcie do jednego z tych sklepów internetowych, więc nie mam kontroli nad rzeczywistą drukarką.
LBogaardt
1

Poprzednie odpowiedzi są bardzo dobre.

Dodam tylko „psychologiczne aspekty” formatu jpg.

Jeśli plik jpg jest dobrze przygotowany, traci tylko około 0,5% informacji. To w zdecydowanej większości przypadków coś, czego ludzkie oko nie widzi. Potrzebujesz programu do wykonania analizy i zobaczenia różnic (takich jak analiza, którą właśnie wykonał Ilmari).

„Dobra jakość” to proces, nie tylko sposób, w jaki format pliku zapisuje obraz. Tak, ponownie skompresowałeś plik za pomocą jpg, ponieważ naprawdę go potrzebujesz. Jeśli jest to sytuacja kontrolowana, można to zrobić.

Ty naprawdę potrzebne to oznacza, że nie można użyć innego formatu bezstratnego, masz bardzo specyficzne potrzeby przechowywania lub programowo bardzo napięty pracy.

Jeśli naprawdę martwisz się jakością, prawdopodobnie nie używałbyś Paint. Format JPG ma kilka konfiguracji, których w ogóle nie można kontrolować w programie Paint.

Oto moja lista darmowych programów, w których naprawdę możesz kontrolować kompresję jpg, oraz opcję, którą musisz wybrać. (Wszystkie z nich w oknie dialogowym zapisu jpg)

Irfanview - Włącz Wyłącz podpróbkowanie kolorów chroma.

FastStone Image Viewer - podpróbkowanie kolorów: brak.

Gimp - podpróbkowanie 4: 4: 4

Wniosek. Nie używaj farby.

Jednej rzeczy jeszcze nie sprawdziłem. Jeśli wszystkie te programy zachowują osadzony profil kolorów. Zmienię swój post później.

Rafael
źródło
Ktoś głosował -1 na tę odpowiedź. Zwykle mnie to nie obchodzi, bo wiem, że mogę powiedzieć coś głupiego. W tym konkretnym przypadku, jaka część odpowiedzi jest nieprawidłowa?
Rafael,
Nie głosowałem (w górę lub w dół), ale może chcesz pracować na pisownię i gramatykę dać lepsze pierwsze wrażenie (a także, uczciwie, aby odpowiedź łatwiejsze do odczytania). Również to pytanie ma już kilka odpowiedzi (a moje, zwłaszcza okazało się dość długie); w pewnym momencie niektóre osoby mogą zacząć głosować (lub przynajmniej nie głosować) odpowiedzi, które nie dodają wyraźnie czegoś nowego do istniejących. Spróbuj także ustrukturyzować swoją odpowiedź, aby ważne bity wyróżniały się na pierwszy rzut oka; w tym przypadku jedyną częścią wyróżnioną pogrubioną czcionką jest nieistotny przypis.
Ilmari Karonen
Dziękuję za komentarz Ilmari. Mam trudności z myśleniem po angielsku, ponieważ nie jest to mój język ojczysty. Poszukam narzędzia pisowni. Nie jestem pewien, czy istnieje gramatyka. - W drugiej części komentarza rozumiem, że logiką stojącą za StackExchange jest niezależne odpowiadanie na pytanie, ponieważ przepływ odpowiedzi nie jest ustalony, ponieważ mogą one zmieniać kolejność lub być edytowane. Zajmę się tym. (Usunąłem pogrubiony tekst) Jeszcze raz dziękuję. : o)
Rafael
1
„traci tylko około 0,5% informacji” [potrzebne źródło] :)
Warren Young,
Cześć Warren, oto: otake.com.mx/Apuntes/PruebasDeCompresion2/... Jest w języku hiszpańskim, na razie skorzystaj z tłumaczenia Google i muszę go zaktualizować. W rzeczywistości jest to mniej niż 0,392% :)
Rafael
0

IrfanView działa dla mnie dobrze dla zestawów obrazów. Oto kilka notatek instruktażowych

Oto moja procedura składowana do wstawiania ramki - Procedura Infran, aby dodać ramkę

  1. Obraz prawym przyciskiem myszy, „Otwórz za pomocą” -> „InfranView”
  2. Naciśnij „b”
  3. Zaznacz „Użyj opcji zaawansowanych” w lewym górnym rogu, naciśnij „Zaawansowane”
  4. Zaznacz „Rozmiar płótna”, naciśnij „Ustawienia”
  5. Wprowadź każdą szerokość ramki (lewa strona, prawa strona, góra, dół)
  6. Wciśnij OK'
  7. Wybierz „Zastąp istniejące pliki”
  8. Wciśnij OK'
  9. Wejdź do katalogu wyjściowego „Katalog wyjściowy dla plików wyników:”
  10. Przejdź do i kliknij dwukrotnie obraz, aby dodać obramowanie na górnej liście. To dodaje go do listy plików wejściowych: na dolnej liście
  11. Naciśnij „Rozpocznij przesyłkę”
J-Dizzle
źródło
1
Czy możesz wyjaśnić, co jest specjalnego w tej metodzie, aby spełniała wymagania plakatu dotyczące nie obniżania jakości obrazu? Przy pierwszym czytaniu wydaje się, że przesyła to JPEG przez cały cykl dekompresyjno-kompresyjny, którego plakat próbuje uniknąć.
Philip Kendall
hmmm, przybliżasz interesujący punkt w odniesieniu do cyklu życia obrazu poprzez proces, który tu wymieniam, nie myślałem o tym. Być może masz rację, jeśli chcesz, żebym usunął lub poprawił mój post, daj mi znać :)!
J-Dizzle,