Предупреждение libpng: iCCP: известен неправильный профиль sRGB


173

Я пытаюсь загрузить изображение PNG с помощью SDL, но программа не работает, и эта ошибка появляется в консоли

Предупреждение libpng: iCCP: известен неправильный профиль sRGB

Почему появляется это предупреждение? Что я должен сделать, чтобы решить эту проблему?



Ответы:


180

Libpng-1.6 более строг в проверке профилей ICC, чем предыдущие версии. Вы можете игнорировать предупреждение. Чтобы избавиться от него, удалите кусок iCCP из изображения PNG.

Некоторые приложения обрабатывают предупреждения как ошибки; Если вы используете такое приложение, вы должны удалить чанк. Вы можете сделать это с любым из множества редакторов PNG, таких как ImageMagick's

convert in.png out.png

Чтобы удалить недействительный кусок iCCP из всех файлов PNG в папке (каталоге), вы можете использовать mogrifyиз ImageMagick:

mogrify *.png

Это требует, чтобы ваш ImageMagick был собран с libpng16. Вы можете легко проверить это, запустив:

convert -list format | grep PNG

Если вы хотите выяснить, какие файлы необходимо исправить, а не обрабатывать их вслепую, вы можете запустить

pngcrush -n -q *.png

где -nсредства не переписывают файлы, а -qсредства подавляют большую часть вывода, за исключением предупреждений. Извините, в pngcrush пока нет возможности подавить все, кроме предупреждений.


Бинарные выпуски ImageMagick находятся здесь


Для проектов Android (Android Studio) перейдите в resпапку.

Например:

C:\{your_project_folder}\app\src\main\res\drawable-hdpi\mogrify *.png

13
С ImageMagick вы можете использовать команду -strip . В частности, я использовал mogrify, чтобы повлиять на все изображения в папке. Моя команда выглядела так: mogrify -strip * .png
Maxito

24
Опция -strip удалит все профили. Если вы опустите опцию -strip ( mogrify * .png ), будут удалены только неправильные профили.
Гленн Рандерс-Персон

2
Есть ли способ узнать, какой файл вызывает предупреждение? Запуск, mogrify **/*.pngкажется, изменяет все файлы в дереве. Я бы предпочел обновить только один неисправный образ.
Uflex

1
Используется find . -type f -name '*.png' -execute mogrify \{\} \;для рекурсивного изменения .pngфайлов в текущем каталоге.
говорит Вэл Восстановить Монику

Если бы бинарные файлы ImageMagick заморозили мой компьютер, возможно, из-за слишком тяжелой работы, и после того, как он ушел на ночь, пришлось принудительно перезагрузить компьютер. Использовал приложение pngcrush, чтобы обнаружить проблему, как уже упоминалось, -owперезаписать и исправить файл, а также уменьшил размер примерно на 1/6! Просто нужно было получить исходный код программы для моего Mac, скомпилировать, установить вручную и запустить его. GitHub Kjuly / pngcrush может иметь предварительно скомпилированный бинарный файл, но не уверен. Sourceforge, казалось, только имел доступный exe-файл Windows и исходный код. Ответ Friederbluemle, кажется, делает это и многое другое.
Пизис

73

Используйте pngcrushдля удаления неправильного профиля sRGB из файла png:

pngcrush -ow -rem allb -reduce file.png
  • -ow перезапишет входной файл
  • -rem allb удалит все вспомогательные фрагменты, кроме tRNS и gAMA
  • -reduce делает без потерь цветового типа или битовой глубины

В выводе консоли вы должны увидеть Removed the sRGB chunkи, возможно, больше сообщений об удалении чанка. В итоге вы получите меньший, оптимизированный файл PNG. Поскольку команда перезапишет исходный файл, обязательно создайте резервную копию или используйте контроль версий.


7
Это сработало! Сделайте это рекурсивно из текущей папки, поместите это в файл .bat: Для / R %% i in (* .png) выполните PNGCRUSH.EXE -ow -rem allb -reduce %% i
Энди Брайс,

13
И однострочник для * nix для рекурсивного исправления всех файлов png в текущем каталоге: find . -type f -iname '*.png' -exec pngcrush -ow -rem allb -reduce {} \;(протестировано на GNU / Linux)
friederbluemle

2
Выше линии по фридеру работает и внутри git bash на окнах.
iKlsR

Pngcrush не удаляет этот кусок в моем случае. Но могущество имиджмагика сделало это.
Никос

25

Решение

Неправильный профиль может быть исправлен с помощью:

  1. Открытие изображения с неправильным профилем с помощью QPixmap :: load
  2. Сохранение изображения обратно на диск (уже с правильным профилем) с помощью QPixmap :: save

Примечание: этом решении используется библиотека Qt .

пример

Вот минимальный пример, который я написал на C ++ для демонстрации того, как реализовать предложенное решение:

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

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

Полный исходный код приложения с графическим интерфейсом на основе этого примера доступен на GitHub .

ОБНОВЛЕНИЕ ОТ 05.12.2019: Ответ был и остается в силе, однако в приложении с графическим интерфейсом, которым я поделился на GitHub, была ошибка, из-за которой выходное изображение было пустым. Я только что исправил это и извиняюсь за неудобство!


4
Я удивлен, что за этот ответ не проголосовали. Он не требует установки ничего и работает ... что еще можно попросить :)
Quantuple

17

Вы также можете просто исправить это в фотошопе ...

  1. Откройте ваш .png файл.
  2. Файл -> Сохранить как и в открывшемся диалоговом окне снимите флажок «Профиль ICC: sRGB IEC61966-2.1»
  3. Снимите флажок «Как копия».
  4. Смело сохраняйте свои исходные файлы .png.
  5. Двигайтесь дальше по жизни, зная, что вы удалили лишь немного зла из мира.

8

Чтобы добавить отличный ответ Гленна, вот что я сделал, чтобы найти, какие файлы были неисправны:

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

Я использовал find и xargs, потому что pngcrush не смог обработать множество аргументов (которые были возвращены **/*.png). -print0и-0 требуется для имен файлов , содержащих дескриптор пространства.

Тогда поиск в выводе этих строк: 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

И для каждого из них запустите mogrify, чтобы исправить их.

mogrify ./Installer/Images/installer_background.png

Это предотвращает изменение фиксации каждого png-файла в хранилище, если только некоторые из них были изменены. Плюс у него есть преимущество, чтобы показать, какие именно файлы были неисправны.

Я протестировал это на Windows с консолью Cygwin и оболочкой zsh. Еще раз спасибо Гленну, который поставил большую часть всего вышеперечисленного, я просто добавляю ответ, поскольку его обычно легче найти, чем комментарии :)


3
В Debian, чтобы найти файлы, которые были проблематичными в моем программном обеспечении, я использовал find . -name "*.png" -exec sh -c 'echo Testing {} && pngcrush -n -q {}' \;Каждый ошибочный PNG, который будет генерироватьсяpngcrush: iCCP: known incorrect sRGB profile
Габриэль Девиллерс

7

Благодаря фантастической ответ от Гленн , я использовал ImageMagik „mogrify * .png“ функциональность «s. Однако у меня были изображения, спрятанные в подпапках, поэтому я использовал этот простой скрипт Python, чтобы применить его ко всем изображениям во всех подпапках и подумал, что это может помочь другим:

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)

2
Это хорошо кроссплатформенное решение, хотя, если вы работаете на платформе, которая поддерживает хорошую оболочку * NIX-y, например Zsh или Bash, вы можете просто использовать mogrify **/*.png.
Кайл Стрэнд

1
Да, хорошая мысль. Я использовал только Python, потому что мы разрабатываем для Windows и Linux и хотели передать этот сценарий в наш репозиторий для будущего использования.
Деван Уильямс

5

Существует более простой способ решить эту проблему с Mac OS и Homebrew:

Установите homebrew, если он еще не установлен

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

или сделать это с каждым файлом в текущем каталоге:

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

Он создаст фиксированную копию для каждого файла png в текущем каталоге и поместит его в подкаталог tmp. После этого, если все в порядке, вам просто нужно переопределить исходные файлы.

Другой совет - использовать приложения Keynote и Preview для создания значков. Я рисую их с помощью Keynote, размером около 120x120 пикселей, поверх слайда с белым фоном (возможность сделать редактируемые полигоны великолепной!). Перед экспортом в Preview я рисую прямоугольник вокруг значка (без заливки и тени, только контур, размером около 135x135) и копирую все в буфер обмена. После этого вам просто нужно открыть его с помощью инструмента «Просмотр», используя «Новый из буфера обмена», выбрать область вокруг значка размером 128x128 пикселей, скопировать, снова использовать «Новый из буфера обмена» и экспортировать его в PNG. Вам не нужно запускать инструмент pngfix.


1
Я не нашел pngfix в стандартной установке ОС El Capitan (или, возможно, я недостаточно хорошо искал), но я нашел его в установке MAMP, которая у меня была. Работал отлично! Спасибо! Upvoted
Гвидо

Ты прав! Я установил его с помощью "brew install libpng" давным-давно.
Адриэль младший

Я получил "n! Ew ERR 08 read Undefined_error: _0 Undefined_error: _0 not_a_PNG_ (too_short) car.png" при запуске этого на 10.13.2.
Митч

@Mitch все еще работает нормально после обновления до 10.13.6.
Адриэль-младший

4

Попробовав пару предложений на этой странице, я решил использовать решение pngcrush. Вы можете использовать скрипт bash ниже для рекурсивного обнаружения и исправления плохих профилей png. Просто передайте ему полный путь к каталогу, в котором вы хотите искать файлы png.

fixpng "/path/to/png/folder"

Сценарий:

#!/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"

2
Это заслуживает большего количества голосов. Все остальные решения затрагивают каждый файл, что особенно плохо, если в системе контроля версий много изображений. Спасибо за сценарий!
kfunk

У меня есть, pngcrush 1.7.85, uses libpng 1.6.21 and zlib 1.2.8но у моего pngcrush нет -warnни -reduceфлагов, так что это решение не работает.
пбхдж

4

некоторая справочная информация по этому вопросу:

Некоторые изменения в libpng версии 1.6+ приводят к тому, что он выдает предупреждение или даже не работает правильно с исходным профилем HP / MS sRGB, что приводит к следующему stderr: предупреждение libpng: iCCP: известен неправильный профиль sRGB Старый профиль использует точку белого D50, где D65 является стандартным. Этот профиль нередко используется Adobe Photoshop, хотя по умолчанию он не был встроен в изображения.

(источник: https://wiki.archlinux.org/index.php/Libpng_errors )

Обнаружение ошибок в некоторых чанках улучшилось; в частности, программа чтения чанков iCCP теперь выполняет довольно полную проверку основного формата. Некоторые плохие профили, которые были ранее приняты, теперь отклоняются, в частности, очень старый сломанный профиль Microsoft / HP sRGB. Требование спецификации PNG о том, что в изображениях с цветным типом 0 или 4 могут появляться только оттенки серого, и что даже если изображение содержит только серые пиксели, в изображениях с цветным типом 2, 3 или 6 могут появляться только профили RGB. Кусок sRGB может появляться на изображениях с любым типом цвета.

(источник: https://forum.qt.io/topic/58638/solved-libpng-warning-iccp-known-incorrect-srgb-profile-drive-me-nuts/16 )


3

Используя программу просмотра изображений IrfanView в Windows, я просто сохранил изображение PNG, и это исправило проблему.


1

Расширяя решение friederbluemle, загрузите pngcrush и затем используйте код, подобный этому, если вы запускаете его для нескольких файлов 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)

здесь все файлы png, связанные с проектами, находятся в 1 папке.


0

Я запустил эти две команды в корне проекта и исправил его.

В основном перенаправьте вывод команды «find» в текстовый файл, чтобы использовать его в качестве списка файлов для обработки. Затем вы можете прочитать этот текстовый файл в «mogrify», используя флаг «@»:

find * .png -mtime -1> list.txt

mogrify - изменить размер 50% @ list.txt

Это позволит использовать «find», чтобы получить все * .png изображения, которые были выпущены ранее, чем за 1 день, и распечатать их в файл с именем «list.txt». Затем «mogrify» читает этот список, обрабатывает изображения и перезаписывает оригиналы версиями с измененным размером. Могут быть небольшие различия в поведении «find» от одной системы к другой, поэтому вам придется проверить страницу руководства для точного использования.


-2

Вот нелепый грубый ответ:

Я изменил скрипт gradlew. Вот моя новая команда exec в конце файла в

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" **| grep -v "libpng warning:"**
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.