libpng ostrzeżenie: iCCP: znany nieprawidłowy profil sRGB

173

Próbuję załadować obraz PNG za pomocą SDL, ale program nie działa i ten błąd pojawia się w konsoli

libpng ostrzeżenie: iCCP: znany nieprawidłowy profil sRGB

Dlaczego pojawia się to ostrzeżenie? Co powinienem zrobić, aby rozwiązać ten problem?

rkarami
źródło
Zobacz tex.stackexchange.com/questions/125612/…
Jesse W at Z - Given up on SE

Odpowiedzi:

180

Libpng-1.6 bardziej rygorystycznie sprawdza profile ICC niż poprzednie wersje. Możesz zignorować ostrzeżenie. Aby się go pozbyć, usuń fragment iCCP z obrazu PNG.

Niektóre aplikacje traktują ostrzeżenia jako błędy; jeśli używasz takiej aplikacji, musisz usunąć fragment. Możesz to zrobić za pomocą dowolnego z różnych edytorów PNG, takich jak ImageMagick

convert in.png out.png

Aby usunąć nieprawidłową porcję iCCP ze wszystkich plików PNG w folderze (katalogu), możesz użyć mogrifyz programu ImageMagick:

mogrify *.png

Wymaga to, aby Twój ImageMagick został skompilowany za pomocą libpng16. Możesz to łatwo sprawdzić uruchamiając:

convert -list format | grep PNG

Jeśli chcesz dowiedzieć się, które pliki należy naprawić, zamiast ślepo przetwarzać je wszystkie, możesz uruchomić

pngcrush -n -q *.png

gdzie -nśrodki nie przepisują plików, a -qśrodki usuwają większość danych wyjściowych z wyjątkiem ostrzeżeń. Przepraszamy, nie ma jeszcze opcji w pngcrush, aby ukryć wszystko oprócz ostrzeżeń.


Binarne wersje programu ImageMagick są tutaj


W przypadku projektów systemu Android (Android Studio) przejdź do resfolderu.

Na przykład:

C:\{your_project_folder}\app\src\main\res\drawable-hdpi\mogrify *.png
Glenn Randers-Pehrson
źródło
13
W programie ImageMagick możesz użyć polecenia -strip . W szczególności użyłem mogrify, aby wpłynąć na wszystkie obrazy w folderze. Moje polecenie wyglądało tak: mogrify -strip * .png
Maxito,
24
Opcja -strip usunie wszystkie profile. Jeśli pominiesz opcję -strip ( mogrify * .png ), tylko nieprawidłowe profile zostaną usunięte.
Glenn Randers-Pehrson
2
Czy istnieje sposób sprawdzenia, który plik powoduje wyświetlenie ostrzeżenia? Uruchomienie mogrify **/*.pngwydaje się modyfikować wszystkie pliki w drzewie. Wolałbym zaktualizować tylko jeden wadliwy obraz.
Uflex
1
Służy find . -type f -name '*.png' -execute mogrify \{\} \;do rekurencyjnej modyfikacji .pngplików w bieżącym katalogu.
Val mówi Przywróć Monikę
Gdyby binaria ImageMagicka zamroziły mój komputer, być może z powodu zbyt ciężkiej pracy i po opuszczeniu na noc, musiałem siłą uruchomić ponownie. Użyłem aplikacji pngcrush do wykrycia wspomnianego problemu, -ownadpisania i naprawy pliku, a także zmniejszenia rozmiaru o około 1/6! Wystarczyło pobrać kod źródłowy programu dla mojego Maca, skompilować, zainstalować ręcznie i uruchomić. GitHub Kjuly / pngcrush może mieć prekompilowany plik binarny, ale nie jestem pewien. Wydawało się, że Sourceforge ma tylko pliki exe systemu Windows i kod źródłowy. Wydaje się, że odpowiedź Friederbluemle robi to, a nawet więcej.
Pysis
73

Użyj, pngcrushaby usunąć nieprawidłowy profil sRGB z pliku png:

pngcrush -ow -rem allb -reduce file.png
  • -ow nadpisze plik wejściowy
  • -rem allb usunie wszystkie pomocnicze fragmenty z wyjątkiem tRNS i gAMA
  • -reduce wykonuje bezstratną redukcję typu koloru lub głębi bitowej

W wynikach konsoli powinieneś zobaczyć Removed the sRGB chunki być może więcej komunikatów o usuwaniu porcji. Otrzymasz mniejszy, zoptymalizowany plik PNG. Ponieważ polecenie nadpisze oryginalny plik, utwórz kopię zapasową lub użyj kontroli wersji.

friederbluemle
źródło
7
To się udało! Zrób to rekurencyjnie z bieżącego folderu, umieść to w pliku .bat: For / R %% i in (* .png) do PNGCRUSH.EXE -ow -rem allb -reduce %% i
Andy Brice
13
I jedna linijka dla * nix, aby rekurencyjnie naprawić wszystkie pliki png w bieżącym katalogu: find . -type f -iname '*.png' -exec pngcrush -ow -rem allb -reduce {} \;(Testowane na GNU / Linux)
friederbluemle
2
Powyższa linia autorstwa Friedera działa również w git bash w oknach.
iKlsR
Pngcrush nie usuwa tego fragmentu w moim przypadku. Ale imagemagick's mogrify to zrobił.
Nikos
25

Rozwiązanie

Nieprawidłowy profil można naprawić przez:

  1. Otwieranie obrazu z nieprawidłowym profilem za pomocą QPixmap :: load
  2. Zapisywanie obrazu z powrotem do dysku (już z właściwego profilu) przy użyciu QPixmap :: save

Uwaga: to rozwiązanie wykorzystuje bibliotekę Qt .

Przykład

Oto minimalny przykład, który napisałem w C ++, aby zademonstrować, jak wdrożyć proponowane rozwiązanie:

QPixmap pixmap;
pixmap.load("badProfileImage.png");

QFile file("goodProfileImage.png");
file.open(QIODevice::WriteOnly);
pixmap.save(&file, "PNG");

Kompletny kod źródłowy aplikacji GUI oparty na tym przykładzie jest dostępny na GitHub .

AKTUALIZACJA OD 05.12.2019: Odpowiedź była i nadal jest ważna, jednak wystąpił błąd w aplikacji GUI, którą udostępniłem na GitHub, powodując, że obraz wyjściowy był pusty. Właśnie to naprawiłem i przepraszam za niedogodności!

scopchanov
źródło
4
Dziwię się, że ta odpowiedź nie została pozytywnie oceniona. Nie wymaga niczego instalowania i działa ... o co więcej można prosić :)
Quantuple
17

Możesz też po prostu to naprawić w Photoshopie ...

  1. Otwórz plik .png.
  2. Plik -> Zapisz jako iw oknie, które się otworzy, odznacz pole „Profil ICC: sRGB IEC61966-2.1”
  3. Odznacz „Jako kopia”.
  4. Odważnie zachowaj oryginalny plik .png.
  5. Kontynuuj swoje życie, wiedząc, że usunąłeś ze świata tylko tę odrobinę zła.
Spencer
źródło
8

Aby dodać do świetnej odpowiedzi Glenna, oto, co zrobiłem, aby znaleźć, które pliki były wadliwe:

find . -name "*.png" -type f -print0 | xargs \
       -0 pngcrush_1_8_8_w64.exe -n -q > pngError.txt 2>&1

Użyłem find i xargs, ponieważ pngcrush nie mógł obsłużyć wielu argumentów (które zostały zwrócone przez **/*.png). Element -print0i -0jest wymagany do obsługi nazw plików zawierających spacje.

Następnie wyszukaj w wyjście dla tych linii: iCCP: Not recognizing known sRGB profile that has been edited.

./Installer/Images/installer_background.png:    
Total length of data found in critical chunks            =     11286  
pngcrush: iCCP: Not recognizing known sRGB profile that has been edited

I dla każdego z nich uruchom mogrify, aby je naprawić.

mogrify ./Installer/Images/installer_background.png

Takie postępowanie zapobiega zmianie każdego pliku png w repozytorium przez zatwierdzenie, gdy tylko kilka z nich zostało faktycznie zmodyfikowanych. Dodatkowo ma tę zaletę, że pokazuje dokładnie, które pliki były wadliwe.

Przetestowałem to na Windowsie z konsolą Cygwin i powłoką zsh. Jeszcze raz dziękuję Glennowi, który umieścił większość z powyższych, po prostu dodaję odpowiedź, ponieważ zwykle łatwiej ją znaleźć niż komentarze :)

Uflex
źródło
3
W Debianie, aby znaleźć pliki, które były problematyczne w moim oprogramowaniu, użyłem find . -name "*.png" -exec sh -c 'echo Testing {} && pngcrush -n -q {}' \;każdego błędnego pliku PNG wygenerujepngcrush: iCCP: known incorrect sRGB profile
Gabriel Devillers
7

Dzięki fantastycznej odpowiedź od Glenn użyłem ImageMagick «mogrify * .png» funkcjonalność „s. Jednak obrazy były ukryte w podfolderach, więc użyłem tego prostego skryptu w Pythonie, aby zastosować to do wszystkich obrazów we wszystkich podfolderach i pomyślałem, że może to pomóc innym:

import os
import subprocess

def system_call(args, cwd="."):
    print("Running '{}' in '{}'".format(str(args), cwd))
    subprocess.call(args, cwd=cwd)
    pass

def fix_image_files(root=os.curdir):
    for path, dirs, files in os.walk(os.path.abspath(root)):
        # sys.stdout.write('.')
        for dir in dirs:
            system_call("mogrify *.png", "{}".format(os.path.join(path, dir)))


fix_image_files(os.curdir)
Devan Williams
źródło
2
Jest to ładnie wieloplatformowe, ale jeśli jesteś na platformie, która obsługuje ładną powłokę * NIX-y, taką jak Zsh lub Bash, możesz po prostu użyć mogrify **/*.png.
Kyle Strand
1
Tak, słuszna uwaga. Użyłem Pythona tylko dlatego, że pracujemy na Windowsie i Linuksie i chciałem przekazać ten skrypt do naszego repozytorium do wykorzystania w przyszłości.
Devan Williams
5

Istnieje łatwiejszy sposób rozwiązania tego problemu w systemie Mac OS i Homebrew:

Zainstaluj homebrew, jeśli nie jest jeszcze zainstalowany

$brew install libpng
$pngfix --strip=color --out=file2.png file.png

lub zrobić to z każdym plikiem w bieżącym katalogu:

mkdir tmp; for f in ./*.png; do pngfix --strip=color --out=tmp/"$f" "$f"; done

Utworzy stałą kopię dla każdego pliku png w bieżącym katalogu i umieści ją w podkatalogu tmp. Następnie, jeśli wszystko jest w porządku, wystarczy zastąpić oryginalne pliki.

Kolejną wskazówką jest użycie aplikacji Keynote i Preview do tworzenia ikon. Rysuję je za pomocą Keynote, w rozmiarze około 120x120 pikseli, na slajdzie z białym tłem (opcja edycji wielokątów jest świetna!). Przed wyeksportowaniem do podglądu rysuję prostokąt wokół ikony (bez wypełnienia ani cienia, tylko kontur, o rozmiarze około 135x135) i kopiuję wszystko do schowka. Następnie wystarczy otworzyć go za pomocą narzędzia podglądu, używając opcji „Nowy ze schowka”, zaznaczyć obszar 128x128 pikseli wokół ikony, skopiować, ponownie użyć polecenia „Nowy ze schowka” i wyeksportować do formatu PNG. Nie musisz uruchamiać narzędzia pngfix.

Adriel Jr
źródło
1
Nie znalazłem pngfix w standardowej instalacji systemu operacyjnego El Capitan (a może nie wyszukałem wystarczająco dobrze), ale znalazłem go w instalacji MAMP, którą miałem. Działało idealnie! Dzięki! Głosowano za
guido
Masz rację! Już dawno zainstalowałem go z "brew install libpng".
Adriel Jr
Otrzymałem "n! Ew ERR 08 odczytany Undefined_error: _0 Undefined_error: _0 not_a_PNG_ (too_short) car.png" podczas uruchamiania tego w 10.13.2.
Mitch
@Mitch Nadal działa poprawnie po aktualizacji do 10.13.6.
Adriel Jr
4

Po wypróbowaniu kilku sugestii na tej stronie ostatecznie skorzystałem z rozwiązania pngcrush. Możesz użyć poniższego skryptu bash, aby rekurencyjnie wykryć i naprawić złe profile png. Po prostu podaj pełną ścieżkę do katalogu, w którym chcesz wyszukać pliki png.

fixpng "/path/to/png/folder"

Scenariusz:

#!/bin/bash

FILES=$(find "$1" -type f -iname '*.png')

FIXED=0
for f in $FILES; do
    WARN=$(pngcrush -n -warn "$f" 2>&1)
    if [[ "$WARN" == *"PCS illuminant is not D50"* ]] || [[ "$WARN" == *"known incorrect sRGB profile"* ]]; then
        pngcrush -s -ow -rem allb -reduce "$f"
        FIXED=$((FIXED + 1))
    fi
done

echo "$FIXED errors fixed"
papka
źródło
2
To zasługuje na więcej głosów. Wszystkie inne rozwiązania dotykają każdego pliku, co jest szczególnie złe, jeśli masz dużo obrazów w systemie kontroli wersji. Dzięki za scenariusz!
kfunk,
Mam, pngcrush 1.7.85, uses libpng 1.6.21 and zlib 1.2.8ale mój pngcrush nie ma -warnani -reduceflag, więc to rozwiązanie nie działa.
pbhj
4

kilka podstawowych informacji na ten temat:

Niektóre zmiany w libpng w wersji 1.6+ powodują, że wyświetla ostrzeżenie lub nawet nie działa poprawnie z oryginalnym profilem HP / MS sRGB, prowadząc do następującego błędu standardowego: ostrzeżenie libpng: iCCP: znany nieprawidłowy profil sRGB Stary profil używa punktu białego D50, gdzie D65 jest standardem. Ten profil nie jest rzadkością, jest używany przez Adobe Photoshop, chociaż domyślnie nie był osadzany w obrazach.

(źródło: https://wiki.archlinux.org/index.php/Libpng_errors )

Poprawiono wykrywanie błędów w niektórych fragmentach; w szczególności czytnik fragmentów iCCP wykonuje teraz całkiem kompletną weryfikację podstawowego formatu. Niektóre złe profile, które były wcześniej akceptowane, są teraz odrzucane, w szczególności bardzo stary, uszkodzony profil sRGB Microsoft / HP. Wymóg specyfikacji PNG, zgodnie z którym tylko profile w skali szarości mogą pojawiać się na obrazach o typie koloru 0 lub 4, a nawet jeśli obraz zawiera tylko szare piksele, na obrazach o typie koloru 2, 3 lub 6 mogą pojawiać się tylko profile RGB. Fragment sRGB może pojawiać się na obrazach o dowolnym kolorze.

(źródło: https://forum.qt.io/topic/58638/solved-libpng-warning-iccp-known-incorrect-srgb-profile-drive-me-nuts/16 )

George Birbilis
źródło
3

Używając przeglądarki obrazów IrfanView w systemie Windows, po prostu ponownie zapisałem obraz PNG i to rozwiązało problem.

Neil Roy
źródło
1

Rozszerzając rozwiązanie Friederbluemle, pobierz pngcrush, a następnie użyj takiego kodu, jeśli uruchamiasz go na wielu plikach png

path =r"C:\\project\\project\\images" # path to all .png images
import os

png_files =[]

for dirpath, subdirs, files in os.walk(path):
    for x in files:
        if x.endswith(".png"):
            png_files.append(os.path.join(dirpath, x))

file =r'C:\\Users\\user\\Downloads\\pngcrush_1_8_9_w64.exe' #pngcrush file 


for name in png_files:
    cmd = r'{} -ow -rem allb -reduce {}'.format(file,name)
    os.system(cmd)

tutaj wszystkie pliki png związane z projektami znajdują się w 1 folderze.

sahasrara62
źródło
0

Uruchomiłem te dwa polecenia w katalogu głównym projektu i jego naprawiono.

Zasadniczo przekieruj wyjście polecenia „znajdź” do pliku tekstowego, aby użyć go jako listy plików do przetworzenia. Następnie możesz wczytać ten plik tekstowy do „mogrify”, używając flagi „@”:

znajdź * .png -mtime -1> list.txt

mogrify -resize 50% @ list.txt

To użyje polecenia „find”, aby pobrać wszystkie obrazy * .png nowsze niż 1 dzień i wydrukować je do pliku o nazwie „list.txt”. Następnie „mogrify” czyta tę listę, przetwarza obrazy i zastępuje oryginały wersjami o zmienionym rozmiarze. Mogą występować drobne różnice w zachowaniu funkcji „find” w różnych systemach, więc będziesz musiał sprawdzić stronę podręcznika, aby sprawdzić dokładne użycie.

yadayada
źródło
-2

Oto absurdalnie brutalna odpowiedź:

Zmodyfikowałem skrypt gradlew. Oto moje nowe polecenie exec na końcu pliku w

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" **| grep -v "libpng warning:"**
Milk Run
źródło