libpng warning: iCCP: known incorrect sRGB profile
Asked Answered
M

16

251

I'm trying to load a PNG image using SDL but the program doesn't work and this error appears in the console

libpng warning: iCCP: known incorrect sRGB profile

Why does this warning appear? What should I do to solve this problem?

Microelectronics answered 30/3, 2014 at 14:20 Comment(2)
N
264

Some applications treat warnings as errors; if you are using such an application, you do have to remove the chunk. You can do that with any variety of PNG editors, like ImageMagick.

With Windows CMD prompt, you will need to cd (change directory) into the folder with the images you want to focus on before you can use the commands listed below.

Libpng-1.6 is more stringent about checking ICC profiles than previous versions; you can ignore the warning. To get rid of it, remove the iCCP chunk from the PNG image.

convert in.png out.png

To remove the invalid iCCP chunk from all of the PNG files in a folder (directory), you can use mogrify from ImageMagick:

mogrify *.png

Or for Windows (if ImageMagick is on path):

magick.exe mogrify *.png

This requires that your ImageMagick was built with libpng16. You can easily check it by running:

convert -list format | grep PNG

If you'd like to find out which files need to be fixed instead of blindly processing all of them, you can run

pngcrush -n -q *.png

where the -n means don't rewrite the files and -q means suppress most of the output except for warnings. Sorry, there's no option yet in pngcrush to suppress everything but the warnings.

Note: You must have pngcrush installed.


Binary Releases of ImageMagick are here


For Android Projects (Android Studio) navigate into res folder.

For example:

C:\{your_project_folder}\app\src\main\res\drawable-hdpi\mogrify *.png
Nahshun answered 30/3, 2014 at 18:19 Comment(8)
With ImageMagick you can use the -strip command. Specifically, I used mogrify to affect all images in a folder. My command looked like this: mogrify -strip *.pngBiliary
The -strip option will remove all profiles. If you omit the -strip option (mogrify *.png), only incorrect profiles will be deleted.Nahshun
Is there a way of finding out which file is triggering the warning? Running mogrify **/*.png seems to modify all files in the tree. I would prefer updating only the one faulty image.Cavalcade
Use find . -type f -name '*.png' -execute mogrify \{\} \; to recursively modify .png files in current directory.Desiccator
Had the ImageMagick binaries freeze my computer, maybe from working too hard, and after leaving overnight, had to restart forcefully. Used the pngcrush application to detect the issue as mentioned, -ow to overwrite and fix the file, and also reduced the size by about 1/6th! Just had to get the program's source code for my mac, compile, install manually, and run it. GitHub Kjuly/pngcrush might have a precompiled binary, but not sure. Sourceforge only seemed to have Windows exe's available and the source code. friederbluemle's answer seems to do this and more.Catkin
It may be use option -warn for pngcrush instead of -q that didn't suppress info messages (at least for me).Shannonshanny
I have just used mogrify to fix a bunch of PNG files. It also turned two RGB+alpha images into mono+alpha (2 channels) because they only contained greys. Version: ImageMagick 7.1.1-10 Q16-HDRI running on Intel Mac.Siderosis
I used the command mentioned by @Val. It seems in Ubuntu, the -execute command is used as -exec. This command worked for me to fix the problem recursively find . -type f -name '*.png' -exec mogrify \{\} \;Venge
A
89

Use pngcrush to remove the incorrect sRGB profile from the png file:

pngcrush -ow -rem allb -reduce file.png
  • -ow will overwrite the input file
  • -rem allb will remove all ancillary chunks except tRNS and gAMA
  • -reduce does lossless color-type or bit-depth reduction

In the console output you should see Removed the sRGB chunk, and possibly more messages about chunk removals. You will end up with a smaller, optimized PNG file. As the command will overwrite the original file, make sure to create a backup or use version control.

Apex answered 30/3, 2015 at 2:42 Comment(4)
That worked! Do do it recursively from the current folder put this in a .bat file : For /R %%i in (*.png) do PNGCRUSH.EXE -ow -rem allb -reduce %%iSoninlaw
And a one-liner for *nix to recursively fix all png files in the current directory: find . -type f -iname '*.png' -exec pngcrush -ow -rem allb -reduce {} \; (Tested on GNU/Linux)Apex
Above line by frieder works inside git bash on windows as well.Charter
Pngcrush doesn't remove this chunk in my case. But imagemagick's mogrify did it.Obvious
M
31

Solution

The incorrect profile could be fixed by:

  1. Opening the image with the incorrect profile using QPixmap::load
  2. Saving the image back to the disk (already with the correct profile) using QPixmap::save

Note: This solution uses the Qt Library.

Example

Here is a minimal example I have written in C++ in order to demonstrate how to implement the proposed solution:

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

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

The complete source code of a GUI application based on this example is available on GitHub.

UPDATE FROM 05.12.2019: The answer was and is still valid, however there was a bug in the GUI application I have shared on GitHub, causing the output image to be empty. I have just fixed it and apologise for the inconvenience!

Modification answered 1/11, 2016 at 21:32 Comment(1)
I am surprised that this answer did not get upvoted. It does not require installing anything and it works... what more could one ask for :)Bistre
D
28

You can also just fix this in photoshop...

  1. Open your .png file.
  2. File -> Save As and in the dialog that opens up uncheck "ICC Profile: sRGB IEC61966-2.1"
  3. Uncheck "As a Copy".
  4. Courageously save over your original .png.
  5. Move on with your life knowing that you've removed just that little bit of evil from the world.
Dichroscope answered 26/11, 2017 at 3:32 Comment(2)
I did the trick with Photofiltre 7. Just open the image and then save as a new one over the orginal png. Works fine, thanks for the tipJohns
@Johns Nice. Somehow this is still my top rated answer 4 years later... Just a simple "Save".Dichroscope
C
11

To add to Glenn's great answer, here's what I did to find which files were faulty:

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

I used the find and xargs because pngcrush could not handle lots of arguments (which were returned by **/*.png). The -print0 and -0 is required to handle file names containing spaces.

Then search in the output for these lines: 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

And for each of those, run mogrify on it to fix them.

mogrify ./Installer/Images/installer_background.png

Doing this prevents having a commit changing every single png file in the repository when only a few have actually been modified. Plus it has the advantage to show exactly which files were faulty.

I tested this on Windows with a Cygwin console and a zsh shell. Thanks again to Glenn who put most of the above, I'm just adding an answer as it's usually easier to find than comments :)

Cavalcade answered 13/10, 2016 at 15:30 Comment(2)
On Debian, to find the files that were problematic in my software, I used find . -name "*.png" -exec sh -c 'echo Testing {} && pngcrush -n -q {}' \; Every erroneous PNG will generate pngcrush: iCCP: known incorrect sRGB profileRaychel
@Gabriel, instead of eye-grepping the output, get find to examine it for you: find . -name '*.png' -type f -exec sh -c 'pngcrush -n -q {} 2>&1 | grep -q "known incorrect sRGB"' \; -print (GNU find) or find . -name '*.png' -type f -exec sh -c 'pngcrush -n -q "$1" 2>&1 | grep -q "known incorrect sRGB"' test {} \; -print0 (portable find). And perhaps pipe the results into xargs mogrify...Pelage
P
10

Thanks to the fantastic answer from Glenn, I used ImageMagik's "mogrify *.png" functionality. However, I had images buried in sub-folders, so I used this simple Python script to apply this to all images in all sub-folders and thought it might help others:

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)
Pacemaker answered 11/4, 2016 at 17:1 Comment(2)
This is nicely cross-platform, though if you're on a platform that supports a nice *NIX-y shell such as Zsh or Bash, you can just use mogrify **/*.png.Phycomycete
Yeah, good point. I only used Python because we develop on Windows and Linux and wanted to commit this script to our repo for future use.Pacemaker
S
9

After trying a couple of the suggestions on this page I ended up using the pngcrush solution. You can use the bash script below to recursively detect and fix bad png profiles. Just pass it the full path to the directory you want to search for png files.

fixpng "/path/to/png/folder"

The script:

#!/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"
Subedit answered 17/2, 2017 at 17:6 Comment(4)
This deserves more upvotes. All the other solutions touch every file, which is especially bad if you have lots of images in a version-control system. Thanks for the script!Niue
I have pngcrush 1.7.85, uses libpng 1.6.21 and zlib 1.2.8 but my pngcrush doesn't have -warn nor -reduce flags so this solution doesn't work.Savannasavannah
I've tested your solution but I'm getting this error: find: ‘’: No such file or directory 0 errors fixed" please guide precisely how to address the image folder.Desolate
If you get "0 errors fixed" message, try to change the $WARN message to this: Not recognizing known sRGB profile" So the script looks like this: code #!/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" == "Not recognizing known sRGB profile" ]]; then pngcrush -s -ow -rem allb -reduce "$f" FIXED=$((FIXED + 1)) fi done echo "$FIXED errors fixed" codeSecure
E
9

There is an easier way to fix this issue with Mac OS and Homebrew:

Install homebrew if it is not installed yet

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

or to do it with every file in the current directory:

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

It will create a fixed copy for each png file in the current directory and put it in the the tmp subdirectory. After that, if everything is OK, you just need to override the original files.

Another tip is to use the Keynote and Preview applications to create the icons. I draw them using Keynote, in the size of about 120x120 pixels, over a slide with a white background (the option to make polygons editable is great!). Before exporting to Preview, I draw a rectangle around the icon (without any fill or shadow, just the outline, with the size of about 135x135) and copy everything to the clipboard. After that, you just need to open it with the Preview tool using "New from Clipboard", select a 128x128 pixels area around the icon, copy, use "New from Clipboard" again, and export it to PNG. You won't need to run the pngfix tool.

Enure answered 22/2, 2017 at 15:59 Comment(4)
I didn't find pngfix in the standard OS El Capitan installation (or perhaps I didn't search well enough), but I found it in the MAMP installation which I had. Worked perfectly! Thanks! UpvotedImport
You are right! I installed it with "brew install libpng" a long time ago.Enure
I got "n!ew ERR 08 read Undefined_error:_0 Undefined_error:_0 not_a_PNG_(too_short) car.png" when running this on 10.13.2.Pleura
@Pleura Still runs ok after upgrading to 10.13.6.Enure
T
7

some background info on this:

Some changes in libpng version 1.6+ cause it to issue a warning or even not work correctly with the original HP/MS sRGB profile, leading to the following stderr: libpng warning: iCCP: known incorrect sRGB profile The old profile uses a D50 whitepoint, where D65 is standard. This profile is not uncommon, being used by Adobe Photoshop, although it was not embedded into images by default.

(source: https://wiki.archlinux.org/index.php/Libpng_errors)

Error detection in some chunks has improved; in particular the iCCP chunk reader now does pretty complete validation of the basic format. Some bad profiles that were previously accepted are now rejected, in particular the very old broken Microsoft/HP sRGB profile. The PNG spec requirement that only grayscale profiles may appear in images with color type 0 or 4 and that even if the image only contains gray pixels, only RGB profiles may appear in images with color type 2, 3, or 6, is now enforced. The sRGB chunk is allowed to appear in images with any color type.

(source: https://forum.qt.io/topic/58638/solved-libpng-warning-iccp-known-incorrect-srgb-profile-drive-me-nuts/16)

Tavi answered 14/4, 2017 at 16:40 Comment(0)
U
4

Using IrfanView image viewer in Windows, I simply resaved the PNG image and that corrected the problem.

Universally answered 5/12, 2015 at 19:33 Comment(0)
L
3

Some of the proposed answers use pngcrush with the -rem allb option, which the documentation says is like "surgery with a chainsaw." The option removes many chunks. To prevent the "iCCP: known incorrect sRGB profile" warning it is sufficient to remove the iCCP chunk, as follows:

pngcrush -ow -rem iCCP filename.png
Lignify answered 21/4, 2021 at 11:53 Comment(0)
E
2

Extending the friederbluemle solution, download the pngcrush and then use the code like this if you are running it on multiple png files

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)

here all the png file related to projects are in 1 folder.

Eliaeliades answered 19/3, 2019 at 10:20 Comment(1)
You don't need to both use a raw string and double up backslashes -- only one or the other is required.Mexico
W
1

When I training yolo, the warninglibpng warning: iCCP: known incorrect sRGB profile occurs each epoch. Then I use bash to find the png, then use python3 and opencv(cv2) to rewrite the png files. So, the warning just occurs when rewriting. Steps as follow:

step 1. Create a python file:

# rewrite.py
import cv2, sys, os
fpath = sys.argv[1]
if os.path.exists(fpath):
    cv2.imwrite(fpath, cv2.imread(fpath))

step 2. In bash, run:

# cd your image dir
# then find and rewrite png file
find . -iname "*.png" | xargs python3 rewrite.py
Whenas answered 21/12, 2022 at 11:59 Comment(0)
C
1

for PHP developers having this issue with imagecreatefrompng function

you can try suppressing the warning using @

$img = @imagecreatefrompng($file);
Caesalpiniaceous answered 28/12, 2022 at 12:38 Comment(0)
B
0

I ran those two commands in the root of the project and its fixed.

Basically redirect the output of the "find" command to a text file to use as your list of files to process. Then you can read that text file into "mogrify" using the "@" flag:

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

mogrify -resize 50% @list.txt

That would use "find" to get all the *.png images newer than 1 day and print them to a file named "list.txt". Then "mogrify" reads that list, processes the images, and overwrites the originals with the resized versions. There may be minor differences in the behavior of "find" from one system to another, so you'll have to check the man page for the exact usage.

Blakeley answered 18/12, 2019 at 21:50 Comment(0)
N
-1

Here is a ridiculously brute force answer:

I modified the gradlew script. Here is my new exec command at the end of the file in the

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" **| grep -v "libpng warning:"**
Nowlin answered 28/4, 2015 at 13:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.