J'essaie de charger une image PNG à l'aide de SDL mais le programme ne fonctionne pas et cette erreur apparaît dans la console.
avertissement libpng: iCCP: profil sRGB incorrect connu
Pourquoi cet avertissement apparaît-il? Que dois-je faire pour résoudre ce problème?
Libpng-1.6 est plus strict en ce qui concerne la vérification des profils ICC que les versions précédentes. Vous pouvez ignorer l'avertissement. Pour vous en débarrasser, supprimez le bloc iCCP de l’image PNG.
Certaines applications traitent les avertissements comme des erreurs. si vous utilisez une telle application, vous devez supprimer le morceau. Vous pouvez le faire avec n’importe quel éditeur au format PNG, comme ImageMagick.
convert in.png out.png
Pour supprimer le bloc iCCP non valide de tous les fichiers PNG d'un dossier (répertoire), vous pouvez utiliser mogrify
à partir d'ImageMagick:
mogrify *.png
Cela nécessite que votre ImageMagick ait été construit avec libpng16. Vous pouvez facilement le vérifier en exécutant:
convert -list format | grep PNG
Si vous souhaitez savoir quels fichiers doivent être corrigés au lieu de les traiter en aveugle, vous pouvez exécuter
pngcrush -n -q *.png
où -n
signifie ne pas réécrire les fichiers et -q
signifie supprimer la plupart des sorties, à l'exception des avertissements. Désolé, pngcrush n'a pas encore la possibilité de tout supprimer, sauf les avertissements.
Les versions binaires d'ImageMagick sont ici
Pour Android Projets (Android Studio), accédez au dossier res
.
Par exemple:
C:\{your_project_folder}\app\src\main\res\drawable-hdpi\mogrify *.png
Utilisez pngcrush
pour supprimer le profil sRGB incorrect du fichier png:
pngcrush -ow -rem allb -reduce file.png
-ow
écrasera le fichier d'entrée-rem allb
supprimera tous les morceaux auxiliaires, à l'exception des tRNS et de gAMA-reduce
effectue une réduction du type de couleur ou de la résolution en bits sans perteDans la sortie de la console, vous devriez voir Removed the sRGB chunk
, et éventuellement plus de messages sur les suppressions de blocs. Vous obtiendrez un fichier PNG optimisé plus petit. La commande écrasant le fichier d'origine, veillez à créer une sauvegarde ou à utiliser le contrôle de version.
Le profil incorrect pourrait être corrigé par:
Remarque: Cette solution utilise la Qt Library .
Voici un exemple minimal que j'ai écrit en C++ afin de montrer comment implémenter la solution proposée:
QPixmap pixmap;
pixmap.load("badProfileImage.png");
QFile file("goodProfileImage.png");
file.open(QIODevice::WriteOnly);
pixmap.save(&file, "PNG");
Le code source complet d'une application graphique basée sur cet exemple est disponible sur GitHub .
Vous pouvez aussi simplement résoudre ce problème dans Photoshop ... J'ai CC2015 mais je suis sûr que c'est la même chose pour toutes les versions.
Pour ajouter à l'excellente réponse de Glenn, voici ce que j'ai fait pour trouver les fichiers défectueux:
find . -name "*.png" -type f -print0 | xargs \
-0 pngcrush_1_8_8_w64.exe -n -q > pngError.txt 2>&1
J'ai utilisé find et xargs car pngcrush ne pouvait pas gérer beaucoup d'arguments (qui ont été retournés par **/*.png
). -print0
et -0
sont nécessaires pour gérer les noms de fichiers contenant des espaces.
Puis recherchez dans la sortie ces lignes: 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
Et pour chacun de ceux-ci, exécutez mogrify dessus pour les réparer.
mogrify ./Installer/Images/installer_background.png
Cela évite qu'un commit ne modifie chaque fichier png du référentiel alors que seuls quelques-uns ont été modifiés. De plus, il a l'avantage de montrer exactement quels fichiers étaient défectueux.
J'ai testé cela sur Windows avec un console Cygwin et un shell zsh. Merci encore à Glenn qui a mis la plupart de ce qui précède, j'ajoute simplement une réponse car il est généralement plus facile à trouver que les commentaires :)
Merci à la réponse fantastique de Glenn , j’ai utilisé la fonctionnalité "mogrify * .png" de ImageMagik . Cependant, j'avais des images enfouies dans des sous-dossiers, j'ai donc utilisé ce simple script Python pour l'appliquer à toutes les images de tous les sous-dossiers et j'ai pensé que cela pourrait aider les autres:
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)
Il existe un moyen plus simple de résoudre ce problème avec Mac OS et Homebrew:
Installez homebrew s'il n'est pas encore installé
$brew install libpng
$pngfix --strip=color --out=file2.png file.png
ou pour le faire avec chaque fichier du répertoire en cours:
mkdir tmp; for f in ./*.png; do pngfix --strip=color --out=tmp/"$f" "$f"; done
Il créera une copie fixe pour chaque fichier png du répertoire en cours et le placera dans le sous-répertoire tmp. Après cela, si tout va bien, il vous suffit de remplacer les fichiers d'origine.
Une autre astuce consiste à utiliser les applications Keynote et Aperçu pour créer les icônes. Je les dessine à l’aide de Keynote, d’une taille d’environ 120 x 120 pixels, sur une diapositive avec un arrière-plan blanc (la possibilité de rendre les polygones modifiables est excellente!). Avant d'exporter dans Aperçu, je trace un rectangle autour de l'icône (sans aucun fond ni ombre, uniquement le contour, d'une taille d'environ 135 x 135) et je copie tout dans le presse-papiers. Après cela, il vous suffit de l'ouvrir avec l'outil de prévisualisation à l'aide de "Nouveau à partir du Presse-papiers", à sélectionner une zone de 128 x 128 pixels autour de l'icône, à copier, à utiliser à nouveau "Nouveau à partir du Presse-papiers" et à l'exporter au format PNG. Vous n'aurez pas besoin d'exécuter l'outil pngfix.
quelques informations de fond sur ceci:
Certaines modifications apportées à la version 1.6+ de libpng provoquent un avertissement ou ne fonctionnent même pas correctement avec le profil sRGB d'origine HP/MS, ce qui entraîne l'avertissement suivant stderr: libpng: iCCP: profil sRGB incorrect connu L'ancien profil utilise un point blanc D50, où D65 est standard. Ce profil n’est pas rare, étant utilisé par Adobe Photoshop, bien qu’il n’ait pas été intégré par défaut aux images.
(source: https://wiki.archlinux.org/index.php/Libpng_errors )
La détection d'erreur dans certains morceaux s'est améliorée. en particulier, le lecteur de blocs iCCP effectue maintenant une validation assez complète du format de base. Certains mauvais profils précédemment acceptés sont maintenant rejetés, en particulier le très ancien profil cassé Microsoft/HP sRGB. La spécification PNG spécifiant que seuls les profils en niveaux de gris peuvent apparaître dans les images de type de couleur 0 ou 4 et que, même si l'image ne contient que des pixels gris, seuls les profils RVB peuvent apparaître dans les images de type de couleur 2, 3 ou 6 est désormais appliquée. Le bloc sRGB est autorisé à apparaître dans les images avec n'importe quel type de couleur.
Après avoir essayé quelques suggestions sur cette page, j’ai finalement utilisé la solution pngcrush. Vous pouvez utiliser le script bash ci-dessous pour détecter et corriger de manière récursive des profils png incorrects. Il suffit de lui transmettre le chemin d'accès complet au répertoire dans lequel vous souhaitez rechercher des fichiers png.
fixpng "/path/to/png/folder"
Le scénario:
#!/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"
En utilisant la visionneuse d’images IrfanView sous Windows, j’ai simplement réenregistré l’image PNG et le problème a été corrigé.
En étendant la solution friederbluemle, téléchargez le pngcrush , puis utilisez le code comme celui-ci si vous l'exécutez sur plusieurs fichiers 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)
ici tous les fichiers png liés aux projets sont dans 1 dossier.