From 2845e0003ed3a7960257ef19b139627ee69523dc Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 9 Feb 2023 15:14:41 +0000 Subject: [PATCH] Got favicons better supported, can't get transparency right Digging deeper, I don't think PHPGD supports 32bit bmp output which complicates matters. --- app/Uploads/FaviconHandler.php | 19 +++++++++++++++---- public/favicon.ico | Bin 3134 -> 3134 bytes 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/app/Uploads/FaviconHandler.php b/app/Uploads/FaviconHandler.php index f61e7ae64..39f8b12ca 100644 --- a/app/Uploads/FaviconHandler.php +++ b/app/Uploads/FaviconHandler.php @@ -28,6 +28,8 @@ class FaviconHandler $bmpData = $image->encode('bmp'); $icoData = $this->bmpToIco($bmpData, 32, 32); +// file_put_contents(public_path('icon.bmp'), $bmpData); +// file_put_contents(public_path('icon-test.png'), $image->encode('png')); file_put_contents($targetPath, $icoData); } @@ -54,6 +56,9 @@ class FaviconHandler { // Trim off the header of the bitmap file $rawBmpData = substr($bmpData, 14); + // Double the height in the "BITMAPINFOHEADER" since, when in an ICO file, half + // of the image data is expected to be a mask. + $rawBmpData[8] = hex2bin(dechex($height * 2)); // ICO header $header = pack('v', 0x00); // Reserved. Must always be 0 @@ -66,17 +71,23 @@ class FaviconHandler $entry .= "\0"; // Color palette, typically 0 $entry .= "\0"; // Reserved + // AND mask +// $pxCount = $width * $height; +// $pxMask = hex2bin('00000000'); +// $mask = str_repeat($pxMask, $pxCount); + $mask = ''; + // Color planes, Appears to remain 1 for bmp image data $entry .= pack('v', 0x01); // Bits per pixel, can range from 1 to 32. From testing conversion - // via intervention from png typically provides this as 32. - $entry .= pack('v', 0x20); + // via intervention from png typically provides this as 24. + $entry .= pack('v', 0x18); // Size of the image data in bytes - $entry .= pack('V', strlen($rawBmpData)); + $entry .= pack('V', strlen($rawBmpData) + strlen($mask)); // Offset of the bmp data from file start $entry .= pack('V', strlen($header) + strlen($entry) + 4); // Join & return the combined parts of the ICO image data - return $header . $entry . $rawBmpData; + return $header . $entry . $rawBmpData . $mask; } } diff --git a/public/favicon.ico b/public/favicon.ico index e047657ccad8c38f318f2bda36f0809a9b0c878f..e114831177f415bd8dfb65b3f6f9d5988796a7b5 100644 GIT binary patch literal 3134 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