From 48f1934387b7a0fb1481182374285a161d96896f Mon Sep 17 00:00:00 2001 From: Dan Brown <ssddanbrown@googlemail.com> Date: Thu, 9 Feb 2023 17:47:33 +0000 Subject: [PATCH] Updated favicon gen to use png-based ICO From testing, worked on Firefox, Chrome, Gnome Web --- .gitignore | 1 + app/Uploads/FaviconHandler.php | 28 +++++++--------------------- public/favicon.ico | Bin 3134 -> 10933 bytes 3 files changed, 8 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 0a858681c..90b80e7b8 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ yarn-error.log /public/js /public/bower /public/build/ +/public/favicon.ico /storage/images _ide_helper.php /storage/debugbar diff --git a/app/Uploads/FaviconHandler.php b/app/Uploads/FaviconHandler.php index 39f8b12ca..2e756c587 100644 --- a/app/Uploads/FaviconHandler.php +++ b/app/Uploads/FaviconHandler.php @@ -25,11 +25,9 @@ class FaviconHandler $imageData = file_get_contents($file->getRealPath()); $image = $this->imageTool->make($imageData); $image->resize(32, 32); - $bmpData = $image->encode('bmp'); - $icoData = $this->bmpToIco($bmpData, 32, 32); + $bmpData = $image->encode('png'); + $icoData = $this->pngToIco($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); } @@ -48,18 +46,12 @@ class FaviconHandler } /** - * Convert BMP image data to ICO file format. + * Convert PNG image data to ICO file format. * Built following the file format info from Wikipedia: * https://en.wikipedia.org/wiki/ICO_(file_format) */ - protected function bmpToIco(string $bmpData, int $width, int $height): string + protected function pngToIco(string $bmpData, int $width, int $height): string { - // 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 $header .= pack('v', 0x01); // Specifies ico image @@ -71,23 +63,17 @@ 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 24. - $entry .= pack('v', 0x18); + $entry .= pack('v', 0x00); // Size of the image data in bytes - $entry .= pack('V', strlen($rawBmpData) + strlen($mask)); + $entry .= pack('V', strlen($bmpData)); // 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 . $mask; + return $header . $entry . $bmpData; } } diff --git a/public/favicon.ico b/public/favicon.ico index e114831177f415bd8dfb65b3f6f9d5988796a7b5..41655ccba55f8dd5f250471eb2e8928b21a85992 100644 GIT binary patch literal 10933 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 XHrNJO5L3!r00000NkvXXu0mjfR=v%1 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