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?
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
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
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.
Solution
The incorrect profile could be fixed by:
Opening the image with the incorrect profile using QPixmap::load
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!
You can also just fix this in photoshop...
Open your .png file.
File -> Save As and in the dialog that opens up uncheck "ICC Profile: sRGB IEC61966-2.1"
Uncheck "As a Copy".
Courageously save over your original .png.
Move on with your life knowing that you've removed just that little bit of evil from the world.
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 :)
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"
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.
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)
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)
Using IrfanView image viewer in Windows, I simply resaved the PNG image and that corrected the problem.
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
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.
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.
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
for PHP developers having this issue with imagecreatefrompng function
you can try suppressing the warning using #
$img = #imagecreatefrompng($file);
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:"**
Related
I want to use ffmpeg to recreate an image file that is uploaded. I know that in PHP you can use imagecreatefromjpeg, imagecreatefrompng and imagejpeg etc. to recreate images. That way, if there is any hidden malware in the original images, it will 'break' / be mangled.
But I want to use this ffmpeg command to recreate image files:
ffmpeg -i in.jpg out.jpg
I have tested converting an image file that has PHP code stored in its EXIF field, and after converting it, the PHP code is no longer executed in the converted file..
Also, the converted file is smaller in size: from 45.9 KB to 11 KB..
Is that a safe way?
EDIT
Btw, I am also checking the MIME type etc, but MIME can be forged, hence recreating image files is recommended.. I want to convert files on another server where there is no PHP installed. That way I can also avoid any potential PHP memory issues.
I've been using http://tools.dynamicdrive.com/favicon/ for years now for generating favicons. I started using it before I even knew how to do any coding (I'm not great now). I don't mind using the utility because the icons always look pretty good, but I'd love to be able to do it locally.
How can I create a favicon locally with a script? Somehow with PHP, imagemagick / gd or maybe sips from the command line?
You could use imagemagik convert. I took these commands from this website.
First make a master image:
convert some_image.bmp -resize 256x256 -transparent white
favicon-256.png
Then we'll want to make images for each size you want to include in
the .ico file.
convert favicon-256.png -resize 16x16 favicon-16.png
convert favicon-256.png -resize 32x32 favicon-32.png
convert favicon-256.png -resize 64x64 favicon-64.png
convert favicon-256.png -resize 128x128 favicon-128.png
Now you'll want to bundle them up into the .ico file, the trick I
found is to make it 256 colors or it will not display properly!
convert favicon-16.png favicon-32.png favicon-64.png favicon-128.png
favicon-256.png -colors 256 favicon.ico
ImageMagick or phpThumb will do this for you but a simpler solution (requiring only PHP and the the GD library) is https://github.com/chrisbliss18/php-ico
Check out this script:
http://bgallz.org/488/php-favicon-generator-script/
I wrote it using PHP to generate a favicon (.ico) file from a jpeg, gif, or png. As ernie above said, most browsers now support image files for icons. This script just alters the extension on the file to be ".ico"
As I have:
// Rename image to .ico file
rename($filename,"./favicon/".$strip_ext.".ico");
I created a project just for this: faviconbuild.
I built it with two simple scripts (one .bat for Windows and one .sh for Unix, Mac, and Windows if using Cygwin). It relies on ImageMagick so you can download the latest version of that for your platform or get it from the ones I include in the releases.
I have released it under the MIT license so feel free to use it for commercial or personal projects or to simply use as inspiration for your own scripts.
I currently use it in my own project like this:
./faviconbuild/faviconbuild.sh -i ./source.png
You can get a full list of the commands available with the -h or --help options.
This will take an input source image and generate all of the output images and a multiresolution .ico, along with the html markup needed for your website.
The script can also be customized by providing a custom text based parse file as input. The current file can be found in the project here. This allows the scripts to be easily extended for any project on all platforms.
Since it is hosted on github I encourage anyone to contribute to the project even if just by submitting a feature request.
I have also published a blog post that goes over the development and serves as a mini tutorial on bash/batch.
All you really need to do is resize an image as a 16x16 file. While the ICO format used to be standard, modern browsers can handle PNG, GIF, and JPG (among other formats).
Resize scripts can easily be found by googling for them, e.g.:
http://www.white-hat-web-design.co.uk/blog/resizing-images-with-php/
This script updates existing files, you might need to alter it for your project. Remove the "confirm" line, or grab my confirm script to go with it.
WARNING: It will clobber any .png file in the current directory.
#!/bin/bash -eu
# public domain, by Sam Watkins
echo "You need to run this from a directory containing only the png icons."
confirm "Are you in the icons directory?"
source=`readlink -f "$1"`
chmod -w $source
v convert "$source" -resize 512x512 -background white -alpha remove -alpha off tmp-512-white.png
v convert "$source" -resize 512x512 tmp-512.png
sizes="16 32 64 128 256"
favicons=
for W in $sizes; do
F=favicon-${W}x$W.png
v convert tmp-512.png -resize ${W}x$W $F
favicons="$favicons $F"
done
v convert $favicons -colors 256 favicon.ico
for F in *.png; do
case "$F" in
favicon-*)
;;
apple-touch-icon*)
v convert tmp-512-white.png -resize `identify -format "%wx%h" "$F"` "$F"
;;
*)
v convert tmp-512.png -resize `identify -format "%wx%h" "$F"` "$F"
;;
esac
done
rm -f tmp-512-white.png tmp-512.png
https://ucm.dev/b/make-icons
https://ucm.dev/b/confirm
imagemagick convert does not work through php shell_exec but does through a shell.
In a shell convert file.pdf file.png works fine. But when I have this within a php file as shell_exec('convert file.pdf file.png'); Then I get no output! I have the permissions to do this, so I think it isn't that that's the problem; I have checked the directory I am in by way of getcwd() and this is also ok.
I know shell_exec works because I have used it earlier in the code and that works fine.
Any ideas?
I got the solution thanks to Crontab from another thread. I quote from there:
[I]f you're trying to convert a PDF to a PNG using ImageMagick ...
even using the full path to ImageMagick's convert won't work if the
script's PATH doesn't contain the path location to Ghostscript also.
Without messing with any user paths, you could add:
putenv("PATH=/usr/local/bin:/usr/bin:/bin");
Or something similar depending on your setup. The gs executable has
to be in your script user's path somewhere or ImageMagick will fail to
convert PDF or EPS files.
Try the full path to convert, i.e. shell_exec('/usr/bin/convert file.pdf file.png);. You can use which convert to find the location on your system.
There are several reason why this could happen, but I suggest reading this page and the user comments:
http://php.net/manual/en/function.shell-exec.php
I tried the sample codes for imagemagick and it was able to save out document previews to the folder on the server.
I tried sample code for fpdf and it was able to render the PDF file fine when it is sent but fails when I ask it to save for directory.
Researching online it says the resolution to the fpdf issue is to set file permission to 777 (any source access permitted, as I understand). My default folder permission is 755.
I want to ask if anyone knows why I can save with imagemagick but not with fpdf.
The reason, I suspect, is because imagemagick calls requires exec() which is effectively command line access. As I understand it however, fpdf is just a PHP wrapper for PDF libraries already present on the server so should have the same availability to exec().
Haven't had a chance to go through the code of fpdf yet but as I am a noob to PHP I don't think that is going to be particularly enlightening.
Please help!
EDIT:
As requested
FPDF
$pdf->Output('testdocument.pdf', 'F');
http://www.fpdf.org/en/doc/output.htm
Imagmagick
exec('convert "docprev.pdf[0]" -colorspace RGB -geometry 200 "document2.png"');
So those are the output commands of FPDF and Imagemagick respectively.
I'm trying to take a generated html file and convert it to PDF on the fly with PHP.
It's going on my localhost and staying there so for the PDF conversion I'm using a Mac OSX utility, I guess you would call it.
The terminal command being:
/System/Library/Printers/Libraries/convert -f temporary.html -o destination/final.pdf
This works properly via terminal (produces a simple 20kb PDF file); however, when I run it inside PHP via passthru() the file (final.pdf) is created though it is a Zero KB file (corrupt).
The /destination folder is CHMOD 777, temporary.html is CHMOD 755.
Any help would be greatly appreciated.
Edit (Additional Detail):
Now in the error log, amongst the debug lines there is an error of "ERROR: xhtmltopdf (PID 13204) crashed on signal 6!"
I like to share what I do to generate PDF file on the fly. We use UNIX server to host.
I use tcpdf - a php library to convert HTML to PDF file. I use it in my projects and it works very well. TCPDF supports css, javascript, forms, images and lot more.
Website: http://www.tcpdf.org/
Demos: http://www.tcpdf.org/examples.php
When I need convert HTML in PDF I use this very nice software: http://www.princexml.com
You could have a look, it's free for personal use.