PHP ICO to PNG conversion

8 comments

Posted on 17th February 2009 by admin in Computers | Web Development

, , , , ,

A few posts ago I wrote about using a PHP class to convert an ICO image to a PNG (or GIF or JPG). I just discovered a bug in the class.

I ran into a problem where some red and orange ICO images turned blue during the conversion. Reading this forum post made me realize that the red and blue values were switched somewhere in class.ico.php. With some experimentation I found it:

In class.ico.php, lines 264-267 need to be changed from

$c[$i] = $this->AllocateColor($im, $this->formats[$index]['colors'][$i]['red'],
         $this->formats[$index]['colors'][$i]['green'],
         $this->formats[$index]['colors'][$i]['blue'],
         round($this->formats[$index]['colors'][$i]['reserved'] / 255 * 127));

to

$c[$i] = $this->AllocateColor($im, $this->formats[$index]['colors'][$i]['blue'],
         $this->formats[$index]['colors'][$i]['green'],
         $this->formats[$index]['colors'][$i]['red'],
         round($this->formats[$index]['colors'][$i]['reserved'] / 255 * 127));

(Note that the blue and red values are indeed switched.) After changing this, it works like a charm for me.

  • Share/Bookmark
8 Comments
  1. secret :) says:

    Great! keep the good work!

    For the convenient of others, here’s a quote from the first post:
    ————
    Here’s how you use the class:
    GetIcon(0))) die(“Could not load ICO.”);
    else {
    header(“Content-Type: image/png”);
    imagepng($r);
    }
    ?>
    ————

    And I’ve modified a bit your class, sometimes I just want to get the best quality icon (that’s usually the last icon in the file) so I’ve replaced this:
    ———–
    function &GetIcon($index) {
    if (!isset($this->formats[$index])) {
    ———–
    with this:
    ———–
    function &GetIcon($index=null) {
    if (is_null($index)) {
    $index = count($this->formats)-1;
    }
    if (!isset($this->formats[$index])) {
    ———–
    so I can omit the $index parameter and get the best icon (assuming he’s the last one)

    Good luck everyone!

    17th February 2009 at 4:25 pm

  2. Dp76 says:

    Hello, First of all thanks for your work :)
    But, please, update zip file as well.
    Your zip file have previous version without fixes.

    17th February 2009 at 9:57 am

  3. GarykPatton says:

    Hello, can you please post some more information on this topic? I would like to read more.

    17th February 2009 at 7:42 am

  4. CrisBetewsky says:

    I’m glad that after surfing the web for uch a long time I have found out this information. I’m really lucky.

    17th February 2009 at 2:29 pm

  5. KonstantinMiller says:

    I have been looking looking around for this kind of information. Will you post some more in future? I’ll be grateful if you will.

    17th February 2009 at 4:32 pm

  6. Vahan says:

    wanna see something cool?

    < ?php
    error_reporting(0);
    require 'class.ico.php';
    // load the .ico
    $ico = new Ico('favicon.ico');
    // now we're going to find the highest quality icon! first we need to know about each icon's image quality...
    for($index = 0; $index TotalIcons(); $index++){
    $icon = $ico->GetIconInfo($index);
    $icons[$index]['width'] = $icon['Width'];
    $icons[$index]['bitcount'] = $icon['BitCount'];
    }
    // sort by width, then bitcount (ascending). you can change the priority if you like by switching them around above
    asort($icons);
    // get the key of the last icon (highest quality) in the sorted list
    $best = end(array_keys($icons));
    // now make a png
    if(!($png=$ico->GetIcon($best))) die(“Could not load ICO.”);
    else {
    header(“Content-Type: image/png”);
    imagepng($png);
    }
    // win!
    ?>

    with a bit more effort, i use this to generate image preview tooltips in apache’s autoindex [=

    17th February 2009 at 12:25 am

  7. Vahan says:

    wordpress broke my loop! anyway it should be:
    for($index = 0; $index LESSTHAN $ico->TotalIcons(); $index++){

    17th February 2009 at 12:29 am

  8. Tony says:

    wanna see something cool?

    GetIconInfo($index);
    $icons[$index]['width'] = $icon['Width'];
    $icons[$index]['bitcount'] = $icon['BitCount'];
    }
    // sort by width, then bitcount (ascending). you can change the priority if you like by switching them around above
    asort($icons);
    // get the key of the last icon (highest quality) in the sorted list
    $best = end(array_keys($icons));
    // now make a png
    if(!($png=$ico->GetIcon($best))) die(“Could not load ICO.”);
    else {
    header(“Content-Type: image/png”);
    imagepng($png);
    }
    // win!
    ?>

    with a bit more effort, i use this to generate image preview tooltips in apache’s autoindex [=

    17th February 2009 at 2:57 am

Leave a comment