From 2845e0003ed3a7960257ef19b139627ee69523dc Mon Sep 17 00:00:00 2001 From: Dan Brown <ssddanbrown@googlemail.com> 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 zcmd5;X-pht7+(JiODm<KMr*B#Mon$JVm)d-qQ+QbVzp6Q6QlKPjQ&uGX(egGa<m+_ z2nw`P<S4XMkXo=DrRA`tWoCC_mt}93W$%0T1nM*U?F>VqhEjgGJG=Sjo%eg*?|t5D zM4}t;U9(1n|C>b_H;P1QB9SNqKZrz|@MGoi51#$+KC#PFxWYkKY$k@q@}3WXk+5%~ zTO!TBMP0i!U{w%v*KdWznTa~24Z{Z>q_UI9MdzlDw`GO{_UmzkoX}^wsH%E}M;<BJ zK<C^<Zsmn{SqCelQ=x0MLXd-AlfLB(O0pt>R-9p@YJ)C=-z**b{SDrtvivEJ=1lDJ zVuJ$kNHk#XEtKuMjeyX(t0y|M7^mKN>N`3ob@cE{UgLSEqII}r17}67X?UM;YRJK^ z78LgBOf0_f;n|Ii+XFVG^+LI<U@a$1f>ZiGK4Bc1$=;$l$LPq4ggn5RZvsNUMLy5* zZnwHi@ynAuva<XcxI=EG`L~+S?qi%<ee)a|?Nm){I&y`T=yXJ0d_UPJFI<PfAqh1{ z-=(sXi4c)>Dp~?oCEU?8?x3>8oP51wq}e+@C`^OV%ICd?0hSQXm!QuAC^~nQu{|^B z)R{W=(79;@0SuVW6)+B*^HVUR{B@&S-RaSEE6SfH3iwwYdEGxTWS2G0rm-YN*Yr`) zZ6sDgL6@d(8z{039g!7hBsPNQ=Fh<Zc#v}8jz1D>j=l#6t%DVCmMGIXD-Eq*F-~2) z4AY4a98R3cjmCno;x+UuD>o;Qairf~_Kja~jx>*ytmlN{vFa_d{kJCobJI*6KL(Lk zZQrBfh)}lw4om+*#y+M!{vjnvaLBj}(dn?f@E)QweBc3i3V&7ATR7w-MAoA{i_ByL z+Omt1tR#=*Mfci<s{NK>b?sYxuoR__xm0aleV?-OIj8|Y=$ph-X<qt7cQ)hF8Ct)F zzX^oGb+(I#*>KlygU;~5hn&Mr@w$F>)_Ub;kG>a}iqc0pVKUpPEOPr$HG&%sxpgOY z2JC9fKnZ*#I&7b5{{fXXetI`T&uwJ8kgDo6-^3-S{5Z^UaxpmJ5I7EVQjsvxC<Ff8 z>W(?q>)#1jM{Jj>WJPy#2#NkiZfVI1!=JklP;*b7G@lD7%YXzK$TGlj2!2qxd}=Am zo^Xx*?a`f6Ry?~PvQUU{Pxk%9IMlimAM*j_B1n-40zVREsGL=@f;%n$lrnae_Sgq} z1qsovwpNrr;!^(QG4zifdV$wL2BPkefg!&wIu#yo-_2%k*Iqg=;ViGYxJ9zM=1u>k z+)mZXi|<QpiC0i0>IeU*g0Y&di-VdI2;mkqSmUX0krJlPEWT5LA9TF9i4gb!OTsNn zSj!66TF#dTY@^zS?ckZ<lcowQA-~ml@*93mEr?G`QXKLob=}*1P0d$RaGfd?unRjj zOyIhrT?@C<60xFeBeK`6?QyHx6=jbLp9<H=TerF!XhMA65i)MjnfWb94~&(d*NjXs zwq?S1ZQ~B`U>W$CuS!mtEw`XsPfj}@pSOZ>ImwSpNs6KQGng><<l|k1K+$=tO<jA@ zmy9P9T}4^3$)oT4Z)DygQHziJFUhz^uZ~Xy)YMK&l0vK?C+&2--%Q!*y4X~BK~8wg z`3qu2__~7m?i^{soEkm!B1~W&nNIJCguT~_EVRX1nT|RHa|#myXLiVrF^(~E2BH4a g*1+Lj7t=BQ-I}iDLgvpy07JgXCA`1!Aj`P;7iM)(t^fc4 literal 3134 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 JG-yoG{{`3W2Q>fy