For the past couple of weeks, I have worked on creating a PHP library to create ICO files. This has been difficult as all the documentation for the ICO format is either sparse or not completely documented.
I’m doing this since I have yet to find a way of creating a valid favicon file using just PHP and PHP’s GD library. Sure, I can create a PNG file and change the extension to “.ico”, but that doesn’t work in all browsers, on all operating systems (such as Windows XP), and is more of a hack than a valid method for creating favicon files.
So, it is time to make one. I have a placeholder github repository named php-ico.
The primary goal is to make a robust, reliable library that creates valid ICO files that can be properly rendered on Windows XP+ and all the major browsers. Thus, my initial goal is not to support every format that exists nor is it to support parsing the ICO files. If the project gets enough attention, I’ll look at expanding the scope.
Here are the resources that I’ve found helpful as I’ve worked on this project:
- ICO (file format) – Wikipedia article about the ICO file format. This has a very comprehensive description of the ICO header. It is sparse on details about the format of the image data.
- BMP file format – Wikipedia article about the BMP file format. This helped me understand the headers and pixel data format for the BMP image data.
- Portable Network Graphics – Wikipedia article about the PNG file format. This gave me what I needed to know to identify PNG image data.
- Windows Bitmap File Format – Very good article that delves into more details about the BMP file format. The extra details about the different types of headers, compression methods, compression encoding, and examples were very helpful.
- Icons – A Microsoft Developer Network article from 1995 that provides the original ICO file format spec. While this is the most authoritative, I really didn’t find this to be as much help as other sources.
- Replacing ICON resources in EXE and DLL files – Article from The Code Project that has a breakdown of the format similar to what is found in the MSDN article. Example C code is provided.
- Support Vista-style ICO files – Mozilla Bugzilla filed bug. The discussion has some great information about methods used to reliably parse varying ICO formats and structures. It also has some good test ICO files to try.
- Convert HBITMAP to .ICO file – This Chironex Software blog post provided the last piece I needed: how to structure the opacity mask data. Where he found this information (since I didn’t find it in any of the above articles) I haven’t a clue.
If this post gets some traction and interest, I’ll consider putting together a post detailing all the different pieces I’ve found here. I’m not a spec writer, but I’d try my best. Let me know if you’d like to have me work on this.
Did I help you?
Thanks for this post, i’ve been using the method of changing the file extension of a PNG for ages, I was completely unaware that it didnt work across all platforms :S time to look back at some of my websites I think
Well, it may have taken a year, but I think this post might finally be gaining some interest. I’be taken this project on as well, hopefully your github repo has seen some activity 🙂 headed there next.
Hi Chris,
I have spent most of today trying to find a way to convert an image to ICO format using only PHP and the GD Library but as you have already worked out, there does not seem to be any solution available.
ImageMagick and phpThumb seem to be the closest alternatives.
I’d like to see a few more comments here to motivate you into action hence this feedback!
Thanks,
Neil
Thanks for the interest Neil. When I posted this, I expected to get lots of feedback. When the feedback was nearly non-existent, I figured that I must be the only person to have this frustration. Your attention prompted action however. The PHP ICO library is now on GitHub. You can find it here.
Awesome!
Thanks so much for sharing this.
I am sure there are lots of folks that aren’t necessarily very good at leaving comments or saying thank-you, but very happy (like me) to download your contribution for free!
All the best,
Neil.
Please let me know how it functions for you. I haven’t gotten any outside feedback, so having any would be helpful.
Hi Chris,
Thanks so much for such a great tool! Your instructions are very clear and I had it running very quickly.
I have been testing out the resulting favicon.ico file on various browsers on Windows, Mac and Linux this evening and apart from some strange behaviour on IE8 (an IE8 issue rather than a favicon issue), everything looks perfect.
Internet Explorer 8 insists on displaying the old favicon file despite clearing the cache and history etc. I could see the new favicon.ico file being used when I added a bookmark but could not get the new favicon to display in the favicon area. I found some good advice at: http://jeffcode.blogspot.com.au/2007/12/why-doesnt-favicon-for-my-site-appear.html which mainly applies to IE7 but I assume is probably valid for IE8 too.
This is par for the course with web browser checking. 20% of the time checking every other browser combination and then about 80% of my time trying to make IE do the right thing!
I’m not going to waste any more time on IE.
All the best,
Neil.
This is because IE has a very aggressive caching mechanism for favicons. The only 100% sure-fire way to get a favicon to refresh on an IE browser is to change the name of the favicon file. I confirmed this in some Microsoft documentation long ago, but I’d rather not dig up the specific resource again right now.
In other words, to ensure that favicon images update properly in all browsers, you should avoid relying upon the browser automatically loading
/favicon.ico
and instead use a<link>
tag in the head section of the page, such as the following:<link rel="shortcut icon" href="/images/favicon-ver-10.ico" />
Note that specs say that just a
rel
of “icon
” should be used, but IE fails to recognize this and requires using both “shortcut
” and “icon
” as it recognizes this not as two separate terms but a single one with a space (which is a spec violation). IE not following spec? Surprising, I know.Note how my example shows a version of the file in the file name. The only way to ensure that a new favicon is loaded is to change it’s name. The two ways I’ve done this in the past is to randomly generate a new name or to add versioning to the file name. Either method works.
Thanks for the tips!
IE is such a pain.
Neil.
THANKS! Since the plugin for Photoshop that I had stopped working suddenly I was looking for a solution for my favicons using GD libraries without success… until now 🙂
Glad to see it getting use beyond my purposes. 🙂
Hi Chris,
I am ready to launch the website I needed PHP-ICO for and have included a little thank-you notice at the bottom of the page at: http://iconifier.net/readme
Thanks once again,
Neil. 🙂
Awesome site Neil. I’m glad the library was able to help you.
Pure awesome.
I used your php class for a cms plugin: https://github.com/dipser/we_tag_favicon
You did a great job! Works wonderful.
Thank you.
Hi,
thank you very much for this library and for the easy to follow instructions on github!
THANKS!
I’m glad that you found it useful.
Hi Chris,
Just a quick check-in to say http://iconifier.net has now generated over 200,000 icon sets with nearly 100,000 happy customers.
Thanks once again, I couldn’t have done this without PHP-ICO.
Neil
That’s amazing news Neil! Thanks for sharing those details and congrats with all the success on your site.