{"id":4454,"date":"2025-05-24T12:51:57","date_gmt":"2025-05-24T12:51:57","guid":{"rendered":"https:\/\/ingenio.vip\/?post_type=tools-pages&#038;p=4454"},"modified":"2025-05-24T12:56:33","modified_gmt":"2025-05-24T12:56:33","slug":"favicon-generator","status":"publish","type":"tools-pages","link":"https:\/\/ingenio.vip\/zh\/tools-pages\/favicon-generator\/","title":{"rendered":"Favicon Generator"},"content":{"rendered":"<div class=\"ingenio-tool favicon-generator-wrapper\" role=\"region\" aria-labelledby=\"favicon-generator-title\">\r\n  <div class=\"favicon-generator\">\r\n    <h2 id=\"favicon-generator-title\">\ud83d\uddbc\ufe0f Favicon Generator<\/h2>\r\n    \r\n    <div class=\"generator-container\">\r\n      <div class=\"upload-section\">\r\n        <div class=\"upload-area\" id=\"upload-area\">\r\n          <div class=\"upload-prompt\">\r\n            <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"48\" height=\"48\" viewbox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n              <path d=\"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7\"><\/path>\r\n              <line x1=\"16\" y1=\"5\" x2=\"22\" y2=\"5\"><\/line>\r\n              <line x1=\"19\" y1=\"2\" x2=\"19\" y2=\"8\"><\/line>\r\n              <circle cx=\"9\" cy=\"9\" r=\"2\"><\/circle>\r\n              <path d=\"M21 15l-3.086-3.086a2 2 0 0 0-2.828 0L6 21\"><\/path>\r\n            <\/svg>\r\n            <h3>Upload Your Image<\/h3>\r\n            <p>Drag & drop your image here or click to browse<\/p>\r\n            <p class=\"file-types\">Supports: JPG, PNG, SVG (Min 64\u00d764px)<\/p>\r\n          <\/div>\r\n          <input type=\"file\" id=\"image-upload\" accept=\"image\/*\" style=\"display: none;\">\r\n        <\/div>\r\n        \r\n        <div class=\"preview-section\" id=\"preview-section\" style=\"display: none;\">\r\n          <div class=\"image-preview\">\r\n            <img decoding=\"async\" id=\"image-preview\" src=\"\" alt=\"Uploaded image preview\">\r\n            <div class=\"preview-controls\">\r\n              <button id=\"change-image\" class=\"action-btn\">\ud83d\udd04 Change Image<\/button>\r\n              <button id=\"reset-image\" class=\"action-btn\">\ud83d\uddd1\ufe0f Reset<\/button>\r\n            <\/div>\r\n          <\/div>\r\n          \r\n          <div class=\"favicon-preview\">\r\n            <h3>Favicon Preview<\/h3>\r\n            <div class=\"favicon-display\">\r\n              <div class=\"favicon-size\">\r\n                <div class=\"favicon-16\">\r\n                  <img decoding=\"async\" id=\"favicon-16\" src=\"\" alt=\"16\u00d716 favicon\">\r\n                  <span>16\u00d716<\/span>\r\n                <\/div>\r\n                <div class=\"favicon-32\">\r\n                  <img decoding=\"async\" id=\"favicon-32\" src=\"\" alt=\"32\u00d732 favicon\">\r\n                  <span>32\u00d732<\/span>\r\n                <\/div>\r\n                <div class=\"favicon-48\">\r\n                  <img decoding=\"async\" id=\"favicon-48\" src=\"\" alt=\"48\u00d748 favicon\">\r\n                  <span>48\u00d748<\/span>\r\n                <\/div>\r\n                <div class=\"favicon-64\">\r\n                  <img decoding=\"async\" id=\"favicon-64\" src=\"\" alt=\"64\u00d764 favicon\">\r\n                  <span>64\u00d764<\/span>\r\n                <\/div>\r\n              <\/div>\r\n              <div class=\"favicon-size\">\r\n                <div class=\"favicon-180\">\r\n                  <img decoding=\"async\" id=\"favicon-180\" src=\"\" alt=\"180\u00d7180 favicon\">\r\n                  <span>180\u00d7180<\/span>\r\n                <\/div>\r\n                <div class=\"favicon-192\">\r\n                  <img decoding=\"async\" id=\"favicon-192\" src=\"\" alt=\"192\u00d7192 favicon\">\r\n                  <span>192\u00d7192<\/span>\r\n                <\/div>\r\n                <div class=\"favicon-512\">\r\n                  <img decoding=\"async\" id=\"favicon-512\" src=\"\" alt=\"512\u00d7512 favicon\">\r\n                  <span>512\u00d7512<\/span>\r\n                <\/div>\r\n              <\/div>\r\n            <\/div>\r\n          <\/div>\r\n        <\/div>\r\n      <\/div>\r\n      \r\n      <div class=\"options-section\">\r\n        <div class=\"generation-options\">\r\n          <h3>\u2699\ufe0f Generation Options<\/h3>\r\n          \r\n          <div class=\"option-group\">\r\n            <label>\r\n              <input type=\"checkbox\" id=\"generate-ico\" checked>\r\n              Generate ICO file (for legacy browsers)\r\n            <\/label>\r\n          <\/div>\r\n          \r\n          <div class=\"option-group\">\r\n            <label>\r\n              <input type=\"checkbox\" id=\"generate-png\" checked>\r\n              Generate PNG files (modern browsers)\r\n            <\/label>\r\n          <\/div>\r\n          \r\n          <div class=\"option-group\">\r\n            <label>\r\n              <input type=\"checkbox\" id=\"generate-apple\" checked>\r\n              Generate Apple touch icons\r\n            <\/label>\r\n          <\/div>\r\n          \r\n          <div class=\"option-group\">\r\n            <label>\r\n              <input type=\"checkbox\" id=\"generate-android\" checked>\r\n              Generate Android icons\r\n            <\/label>\r\n          <\/div>\r\n          \r\n          <div class=\"option-group\">\r\n            <label>\r\n              <input type=\"checkbox\" id=\"generate-webmanifest\" checked>\r\n              Generate webmanifest file\r\n            <\/label>\r\n          <\/div>\r\n          \r\n          <div class=\"option-group\">\r\n            <label for=\"background-color\">Background Color:<\/label>\r\n            <input type=\"color\" id=\"background-color\" value=\"#ffffff\">\r\n            <span class=\"color-value\" id=\"color-value\">#ffffff<\/span>\r\n          <\/div>\r\n          \r\n          <div class=\"option-group\">\r\n            <label for=\"padding\">Padding:<\/label>\r\n            <input type=\"range\" id=\"padding\" min=\"0\" max=\"20\" value=\"0\">\r\n            <span class=\"range-value\" id=\"padding-value\">0px<\/span>\r\n          <\/div>\r\n        <\/div>\r\n        \r\n        <div class=\"download-section\">\r\n          <h3>\ud83d\udce5 Download Package<\/h3>\r\n          <p>Your favicon package will include all selected formats plus HTML code for implementation.<\/p>\r\n          \r\n          <div class=\"download-actions\">\r\n            <button id=\"generate-favicons\" class=\"generate-btn\" disabled>\u2728 Generate Favicons<\/button>\r\n            <button id=\"download-package\" class=\"download-btn\" disabled>\ud83d\udce6 Download All<\/button>\r\n          <\/div>\r\n          \r\n          <div class=\"html-code\" id=\"html-code-section\" style=\"display: none;\">\r\n            <h4>HTML Implementation Code<\/h4>\r\n            <textarea id=\"html-code\" readonly spellcheck=\"false\"><!-- Copy this code to your website's <head> section --><\/textarea>\r\n            <button id=\"copy-html\" class=\"action-btn\">\ud83d\udccb Copy HTML<\/button>\r\n          <\/div>\r\n        <\/div>\r\n      <\/div>\r\n    <\/div>\r\n    \r\n    <div class=\"info-section\">\r\n      <div class=\"info-card\">\r\n        <h3>\u2139\ufe0f About Favicons<\/h3>\r\n        <p>Favicons are small icons displayed in browser tabs, bookmarks, and mobile devices. Modern websites need multiple icon sizes for different devices and platforms.<\/p>\r\n      <\/div>\r\n      \r\n      <div class=\"info-card\">\r\n        <h3>\ud83d\udcf1 Required Sizes<\/h\u6781\r\n>\r\n          <li><strong>16\u00d716<\/strong> - Browser tab icon<\/li>\r\n          <li><strong>32\u00d732<\/strong> - Standard favicon<\/li>\r\n          <li><strong>48\u00d748<\/strong> - Windows taskbar<\/li>\r\n          <li><strong>180\u00d7180<\/strong> - Apple touch icon<\/li>\r\n          <li><strong>192\u00d7192<\/strong> - Android Chrome<\/li>\r\n          <li><strong>512\u00d7512<\/strong> - Progressive Web Apps<\/li>\r\n        <\/ul>\r\n      <\/div>\r\n      \r\n      <div class=\"info-card\">\r\n        <h3>\ud83d\udca1 Best Practices<\/h3>\r\n        <ul>\r\n          <li>Start with at least 64\u00d764px source image<\/li>\r\n          <li>Use simple, recognizable designs<\/li>\r\n          <li>Square images work best<\/li>\r\n          <li>Test on multiple devices<\/li>\r\n          <li>Update browser cache after changing<\/li>\r\n        <\/ul>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<style>\r\n.favicon-generator-wrapper {\r\n  background-color: #f5f5fa;\r\n  padding: 1rem;\r\n}\r\n\r\n.favicon-generator {\r\n  max-width: 1200px;\r\n  margin: auto;\r\n  background: #fff;\r\n  border-radius: 10px;\r\n  padding: 25px;\r\n  box-shadow: 0 4px 12px rgba(0,0,0,0.08);\r\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen-Sans, Ubuntu, Cantarell, \"Helvetica Neue\", sans-serif;\r\n}\r\n\r\n.favicon-generator h2 {\r\n  text-align: center;\r\n  font-size: 1.8rem;\r\n  color: #0a66c2;\r\n  margin-bottom: 1.5rem;\r\n}\r\n\r\n.generator-container {\r\n  display: grid;\r\n  grid-template-columns: 1fr;\r\n  gap: 30px;\r\n}\r\n\r\n.upload-section {\r\n  background: #f9f9f9;\r\n  border-radius: 8px;\r\n  padding: 20px;\r\n}\r\n\r\n.upload-area {\r\n  border: 2px dashed #ccc;\r\n  border-radius: 6\u6781;\r\n  padding: 40px;\r\n  text-align: center;\r\n  cursor: pointer;\r\n  transition: all 0.3s;\r\n}\r\n\r\n.upload-area:hover {\r\n  border-color: #0a66c2;\r\n  background: rgba(10, 102, 194, 0.05);\r\n}\r\n\r\n.upload-prompt svg {\r\n  color: #0a66c2;\r\n  margin-bottom: 15px;\r\n}\r\n\r\n.upload-prompt h3 {\r\n  margin: 0 0 10px;\r\n  color: #333;\r\n}\r\n\r\n.upload-prompt p {\r\n  margin: 5px 0;\r\n  color: #666;\r\n}\r\n\r\n.file-types {\r\n  font-size: 0.85rem;\r\n  color: #999;\r\n}\r\n\r\n.preview-section {\r\n  display: grid;\r\n  grid-template-columns: 1fr 1fr;\r\n  gap: 20px;\r\n}\r\n\r\n.image-preview {\r\n  background: white;\r\n  border-radius: 6px;\r\n  padding: 15px;\r\n  box-shadow: 0 2px 5px rgba(0,0,0,0.05);\r\n}\r\n\r\n.image-preview img {\r\n  max-width: 100%;\r\n  max-height: 200px;\r\n  display: block;\r\n  margin: 0 auto 15px;\r\n  border-radius: 4px;\r\n}\r\n\r\n.preview-controls {\r\n  display: flex;\r\n  gap: 10px;\r\n}\r\n\r\n.action-btn {\r\n  padding: 8px 12px;\r\n  border: none;\r\n  border-radius: 4px;\r\n  background: #e1ebf7;\r\n  color: #0a66c2;\r\n  cursor: pointer;\r\n  font-size: 0.85rem;\r\n  display: flex;\r\n  align-items: center;\r\n  gap: 5px;\r\n  transition: all 0.2s;\r\n}\r\n\r\n.action-btn:hover {\r\n  background: #0a66c2;\r\n  color: white;\r\n}\r\n\r\n.favicon-preview {\r\n  background: white;\r\n  border-radius: 6px;\r\n  padding: 15px;\r\n  box-shadow: 0 2px 5px rgba(0,0,0,0.05);\r\n}\r\n\r\n.favicon-preview h3 {\r\n  margin-top: 0;\r\n  margin-bottom: 15px;\r\n  color: #333;\r\n}\r\n\r\n.favicon-display {\r\n  display: flex;\r\n  flex-direction: column;\r\n  gap: 15px;\r\n}\r\n\r\n.favicon-size {\r\n  display: flex;\r\n  gap: 15px;\r\n  flex-wrap: wrap;\r\n}\r\n\r\n.favicon-16, .favicon-32, .favicon-48, .favicon-64,\r\n.favicon-180, .favicon-192, .favicon-512 {\r\n  text-align: center;\r\n  flex: 1;\r\n  min-width: 100px;\r\n}\r\n\r\n.favicon-16 img, .favicon-32 img, .favicon-48 img, .favicon-64 img,\r\n.favicon-180 img, .favicon-192 img, .favicon-512 img {\r\n  width: 100%;\r\n  max-width: 80px;\r\n  height: auto;\r\n  border: 1px solid #eee;\r\n  margin-bottom: 5px;\r\n}\r\n\r\n.favicon-16 span, .favicon-32 span, .favicon-48 span, .favicon-64 span,\r\n.favicon-180 span, .favicon-192 span, .favicon-512 span {\r\n  display: block;\r\n  font-size: 0.8rem;\r\n  color: #666;\r\n}\r\n\r\n.options-section {\r\n  display: grid;\r\n  grid-template-columns: 1fr 1fr;\r\n  gap: 30px;\r\n}\r\n\r\n.generation-options {\r\n  background: #f9f9f9;\r\n  border-radius: 8px;\r\n  padding: 20px;\r\n}\r\n\r\n.generation-options h3 {\r\n  margin-top: 0;\r\n  margin-bottom: 20px;\r\n  color: #333;\r\n}\r\n\r\n.option-group {\r\n  margin-bottom: 15px;\r\n}\r\n\r\n.option-group label {\r\n  display: flex;\r\n  align-items: center;\r\n  gap: 8px;\r\n  cursor: pointer;\r\n  font-size: 0.95rem;\r\n}\r\n\r\n.option-group input[type=\"checkbox\"] {\r\n  width: 18px;\r\n  height: 18px;\r\n}\r\n\r\n.option-group input[type=\"color\"] {\r\n  width: 40px;\r\n  height: 30px;\r\n  padding: 2px;\r\n  border: 1px solid #ddd;\r\n  border-radius: 4px;\r\n  cursor: pointer;\r\n}\r\n\r\n.color-value {\r\n  font-family: monospace;\r\n  font-size: 0.9rem;\r\n  margin-left: 10px;\r\n}\r\n\r\n.option-group input[type=\"range\"] {\r\n  width: 150px;\r\n  margin-right: 10px;\r\n}\r\n\r\n.range-value {\r\n  font-family: monospace;\r\n  font-size: 0.9rem;\r\n}\r\n\r\n.download-section {\r\n  background: #f9f9f9;\r\n  border-radius: 8px;\r\n  padding: 20px;\r\n}\r\n\r\n.download-section h3 {\r\n  margin-top: 0;\r\n  margin-bottom: 15px;\r\n  color: #333;\r\n}\r\n\r\n.download-section p {\r\n  margin-top: 0;\r\n  color: #666;\r\n  font-size: 0.95rem;\r\n}\r\n\r\n.download-actions {\r\n  display: flex;\r\n  gap: 15px;\r\n  margin: 20px 0;\r\n}\r\n\r\n.generate-btn, .download-btn {\r\n  padding: 12px 20px;\r\n  border: none;\r\n  border-radius: 6px;\r\n  color: white;\r\n  cursor: pointer;\r\n  font-size: 1rem;\r\n  transition: all 0.2s;\r\n  display: flex;\r\n  align-items: center;\r\n  gap: 8px;\r\n}\r\n\r\n.generate-btn {\r\n  background: #0a66c2;\r\n}\r\n\r\n.generate-btn:hover {\r\n  background: #084a9e;\r\n  transform: translateY(-1px);\r\n  box-shadow: 0 2px 5px rgba(0,0,0,0.1);\r\n}\r\n\r\n.download-btn {\r\n  background: #4CAF50;\r\n}\r\n\r\n.download-btn:hover {\r\n  background: #3e8e41;\r\n  transform: translateY(-1px);\r\n  box-shadow: 0 2px 5px rgba(0,0,0,0.1);\r\n}\r\n\r\n.download-btn:disabled, .generate-btn:disabled {\r\n  background: #ccc;\r\n  cursor: not-allowed;\r\n  transform: none;\r\n  box-shadow: none;\r\n}\r\n\r\n.html-code {\r\n  background: white;\r\n  border-radius: 6px;\r\n  padding: 15px;\r\n  margin-top: 20px;\r\n  box-shadow: 0 2px 5px rgba(0,0,0,0.05);\r\n}\r\n\r\n.html-code h4 {\r\n  margin-top: 0;\r\n  margin-bottom: 10px;\r\n  color: #333;\r\n}\r\n\r\n.html-code textarea {\r\n  width: 100%;\r\n  min-height: 120px;\r\n  padding: 10px;\r\n  border: 1px solid #ddd;\r\n  border-radius: 4px;\r\n  font-family: Consolas, Monaco, 'Andale Mono', monospace;\r\n  font-size: 13px;\r\n  line-height: 1.5;\r\n  resize: vertical;\r\n  margin-bottom: 10px;\r\n}\r\n\r\n.info-section {\r\n  display: grid;\r\n  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\r\n  gap: 20px;\r\n  margin-top: 30px;\r\n}\r\n\r\n.info-card {\r\n  background: #f9f9f9;\r\n  border-radius: 8px;\r\n  padding: 20px;\r\n  border-left: 4px solid #0a66c2;\r\n}\r\n\r\n.info-card h3 {\r\n  margin-top: 0;\r\n  margin-bottom: 15px;\r\n  color: #0a66c2;\r\n}\r\n\r\n.info-card ul {\r\n  margin: 0;\r\n  padding-left: 20px;\r\n}\r\n\r\n.info-card li {\r\n  margin-bottom: 8px;\r\n  font-size: 0.95rem;\r\n}\r\n\r\n@media (max-width: 1024px) {\r\n  .preview-section, .options-section {\r\n    grid-template-columns: 1fr;\r\n  }\r\n  \r\n  .download-actions {\r\n    flex-direction: column;\r\n  }\r\n  \r\n  .generate-btn, .download-btn {\r\n    width: 100%;\r\n    justify-content: center;\r\n  }\r\n}\r\n\r\n@media (max-width: 768px) {\r\n  .favicon-size {\r\n    flex-direction: column;\r\n  }\r\n  \r\n  .option-group input[type=\"range\"] {\r\n    width: 100%;\r\n  }\r\n  \r\n  .html-code textarea {\r\n    min-height: 200px;\r\n  }\r\n}\r\n<\/style>\r\n\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jszip\/3.10.1\/jszip.min.js\"><\/script>\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/image2ico@1.0.0\/dist\/image2ico.min.js\"><\/script>\r\n\r\n<script>\r\ndocument.addEventListener(\"DOMContentLoaded\", function() {\r\n  \/\/ DOM elements\r\n  const uploadArea = document.getElementById('upload-area');\r\n  const imageUpload = document.getElementById('image-upload');\r\n  const previewSection = document.getElementById('preview-section');\r\n  const imagePreview = document.getElementById('image-preview');\r\n  const changeImageBtn = document.getElementById('change-image');\r\n  const resetImageBtn = document.getElementById('reset-image');\r\n  const generateBtn = document.getElementById('generate-favicons');\r\n  const downloadBtn = document.getElementById('download-package');\r\n  const htmlCodeSection = document.getElementById('html\u6781-section');\r\n  const htmlCode = document.getElementById('html-code');\r\n  const copyHtmlBtn = document.getElementById('copy-html');\r\n  \r\n  \/\/ Favicon preview elements\r\n  const favicon16 = document.getElementById('favicon-16');\r\n  const favicon32 = document.getElementById('favicon-32');\r\n  const favicon48 = document.getElementById('favicon-48');\r\n  const favicon64 = document.getElementById('favicon-64');\r\n  const favicon180 = document.getElementById('favicon-180');\r\n  const favicon192 = document.getElementById('favicon-192');\r\n  const favicon512 = document.getElementById('favicon-512');\r\n  \r\n  \/\/ Options\r\n  const generateIco = document.getElementById('generate-ico');\r\n  const generatePng = document.getElementById('generate-png');\r\n  const generateApple = document.getElementById('generate-apple');\r\n  const generateAndroid = document.getElementById('generate-android');\r\n  const generateWebmanifest = document.getElementById('generate-webmanifest');\r\n  const backgroundColor = document.getElementById('background-color');\r\n  const colorValue = document.getElementById('color-value');\r\n  const padding = document.getElementById('padding');\r\n  const paddingValue = document.getElementById('padding-value');\r\n  \r\n  \/\/ Canvas for resizing\r\n  const canvas = document.createElement('canvas');\r\n  const ctx = canvas.getContext('2d');\r\n  \r\n  \/\/ Current image data\r\n  let originalImage = null;\r\n  let processedImage = null;\r\n  \r\n  \/\/ Event listeners\r\n  uploadArea.addEventListener('click', () => imageUpload.click());\r\n  uploadArea.addEventListener('dragover', handleDragOver);\r\n  uploadArea.addEventListener('dragleave', handleDragLeave);\r\n  uploadArea.addEventListener('drop', handleDrop);\r\n  imageUpload.addEventListener('change', handleFileSelect);\r\n  changeImageBtn.addEventListener('click', () => imageUpload.click());\r\n  resetImageBtn.addEventListener('click', resetUpload);\r\n  generateBtn.addEventListener('click', generateFavicons);\r\n  downloadBtn.addEventListener('click', downloadPackage);\r\n  copyHtmlBtn.addEventListener('click', copyHtmlCode);\r\n  backgroundColor.addEventListener('input', updateColorValue);\r\n  padding.addEventListener('input', updatePaddingValue);\r\n  \r\n  \/\/ Update color value display\r\n  function updateColorValue() {\r\n    colorValue.textContent = backgroundColor.value;\r\n    if (originalImage) processImage();\r\n  }\r\n  \r\n  \/\/ Update padding value display\r\n  function updatePaddingValue() {\r\n    paddingValue.textContent = `${padding.value}px`;\r\n    if (originalImage) processImage();\r\n  }\r\n  \r\n  \/\/ Handle drag over\r\n  function handleDragOver(e) {\r\n    e.preventDefault();\r\n    e.stopPropagation();\r\n    uploadArea.style.borderColor = '#0a66c2';\r\n    uploadArea.style.backgroundColor = 'rgba(10, 102, 194, 0.1)';\r\n  }\r\n  \r\n  \/\/ Handle drag leave\r\n  function handleDragLeave(e) {\r\n    e.preventDefault();\r\n    e.stopPropagation();\r\n    uploadArea.style.borderColor = '#ccc';\r\n    uploadArea.style.backgroundColor = '';\r\n  }\r\n  \r\n  \/\/ Handle drop\r\n  function handleDrop(e) {\r\n    e.preventDefault();\r\n    e.stopPropagation();\r\n    handleDragLeave(e);\r\n    \r\n    const files = e.dataTransfer.files;\r\n    if (files.length > 0 && files[0].type.match('image.*')) {\r\n      loadImage(files[0]);\r\n    }\r\n  }\r\n  \r\n  \/\/ Handle file selection\r\n  function handleFileSelect(e) {\r\n    const file = e.target.files[0];\r\n    if (file && file.type.match('image.*')) {\r\n      loadImage(file);\r\n    }\r\n  }\r\n  \r\n  \/\/ Load image file\r\n  function loadImage(file) {\r\n    const reader = new FileReader();\r\n    reader.onload = function(e) {\r\n      const img = new Image();\r\n      img.onload = function() {\r\n        \/\/ Check minimum size\r\n        if (img.width < 64 || img.height < 64) {\r\n          alert('For best results, please use an image of at least 64\u00d764 pixels');\r\n          return;\r\n        }\r\n        \r\n        originalImage = img;\r\n        processImage();\r\n        previewSection.style.display = 'grid';\r\n        generateBtn.disabled = false;\r\n      };\r\n      img.onerror = function() {\r\n        alert('Error loading image. Please try another file.');\r\n      };\r\n      img.src = e.target.result;\r\n    };\r\n    reader.onerror = function() {\r\n      alert('Error reading file. Please try again.');\r\n    };\r\n    reader.readAsDataURL(file);\r\n  }\r\n  \r\n  \/\/ Process image with current settings\r\n  function processImage() {\r\n    if (!originalImage) return;\r\n    \r\n    \/\/ Create square canvas based on the longest dimension\r\n    const size = Math.max(originalImage.width, originalImage.height);\r\n    const paddedSize = size + (parseInt(padding.value) * 2);\r\n    \r\n    canvas.width = paddedSize;\r\n    canvas.height = paddedSize;\r\n    \r\n    \/\/ Fill with background color\r\n    ctx.fillStyle = backgroundColor.value;\r\n    ctx.fillRect(0, 0, paddedSize, paddedSize);\r\n    \r\n    \/\/ Calculate centered position with padding\r\n    const x = (paddedSize - originalImage.width) \/ 2;\r\n    const y = (paddedSize - originalImage.height) \/ 2;\r\n    \r\n    \/\/ Draw image\r\n    ctx.drawImage(originalImage, x, y, originalImage.width, originalImage.height);\r\n    \r\n    \/\/ Update preview\r\n    processedImage = new Image();\r\n    processedImage.onload = function() {\r\n      imagePreview.src = this.src;\r\n      generatePreviewFavicons();\r\n    };\r\n    processedImage.src = canvas.toDataURL('image\/png');\r\n  }\r\n  \r\n  \/\/ Generate preview favicons\r\n  function generatePreviewFavicons() {\r\n    if (!processedImage) return;\r\n    \r\n    \/\/ Create temporary canvas for resizing\r\n    const tempCanvas = document.createElement('canvas');\r\n    const tempCtx = tempCanvas.getContext('2d');\r\n    \r\n    \/\/ Function to resize and update an element\r\n    const updateFavicon = (size, element) => {\r\n      if (!element) return;\r\n      \r\n      tempCanvas.width = size;\r\n      tempCanvas.height = size;\r\n      tempCtx.clearRect(0, 0, size, size);\r\n      tempCtx.drawImage(processedImage, 0, 0, size, size);\r\n      element.src = tempCanvas.toDataURL('image\/png');\r\n    };\r\n    \r\n    updateFavicon(16, favicon16);\r\n    updateFavicon(32, favicon32);\r\n    updateFavicon(48, favicon48);\r\n    updateFavicon(64, favicon64);\r\n    updateFavicon(180, favicon180);\r\n    updateFavicon(192, favicon192);\r\n    updateFavicon(512, favicon512);\r\n  }\r\n  \r\n  \/\/ Generate all favicon files\r\n  function generateFavicons() {\r\n    if (!processedImage) return;\r\n    \r\n    \/\/ Generate HTML code\r\n    generateHtmlCode();\r\n    \r\n    \/\/ Enable download button\r\n    downloadBtn.disabled = false;\r\n    htmlCodeSection.style.display = 'block';\r\n  }\r\n  \r\n  \/\/ Generate HTML implementation code\r\n  function generateHtmlCode() {\r\n    let html = `<!-- Favicon HTML for your website -->\\n`;\r\n    \r\n    if (generateIco.checked) {\r\n      html += `<link rel=\"icon\" href=\"\/favicon.ico\" sizes=\"any\">\\n`;\r\n    }\r\n    \r\n    if (generatePng.checked) {\r\n      html += `<link rel=\"icon\" href=\"\/favicon-32x32.png\" type=\"image\/png\" sizes=\"32x32\">\\n`;\r\n      html += `<link rel=\"icon\" href=\"\/favicon-16x16.png\" type=\"image\/png\" sizes=\"16x16\">\\n`;\r\n    }\r\n    \r\n    if (generateApple.checked) {\r\n      html += `<link rel=\"apple-touch-icon\" href=\"\/apple-touch-icon.png\" sizes=\"180x180\">\\n`;\r\n    }\r\n    \r\n    if (generateWebmanifest.checked) {\r\n      html += `<link rel=\"manifest\" href=\"\/site.webmanifest\">\\n`;\r\n    }\r\n    \r\n    if (generateAndroid.checked) {\r\n      html += `<link rel=\"icon\" href=\"\/android-chrome-192x192.png\" sizes=\"192x192\">\\n`;\r\n      html += `<link rel=\"icon\" href=\"\/android-chrome-512x512.png\" sizes=\"512x512\">\\n`;\r\n    }\r\n    \r\n    htmlCode.value = html;\r\n  }\r\n  \r\n  \/\/ Copy HTML code to clipboard\r\n  async function copyHtmlCode() {\r\n    try {\r\n      await navigator.clipboard.writeText(htmlCode.value);\r\n      copyHtmlBtn.textContent = '\u2713 Copied!';\r\n      setTimeout(() => {\r\n        copyHtmlBtn.textContent = '\ud83d\udccb Copy HTML';\r\n      }, 2000);\r\n    } catch (err) {\r\n      alert('Failed to copy text. Please copy manually.');\r\n    }\r\n  }\r\n  \r\n  \/\/ Download complete package as ZIP\r\nasync function downloadPackage() {\r\n    if (!processedImage) return;\r\n    \r\n    try {\r\n        \/\/ Show loading state\r\n        downloadBtn.disabled = true;\r\n        downloadBtn.innerHTML = '\u23f3 Preparing Download...';\r\n        \r\n        \/\/ Create new JSZip instance\r\n        const zip = new JSZip();\r\n        const imgFolder = zip.folder(\"favicons\");\r\n        \r\n        \/\/ Create dedicated canvas for downloads\r\n        const downloadCanvas = document.createElement('canvas');\r\n        const downloadCtx = downloadCanvas.getContext('2d');\r\n        \r\n        \/\/ Generate PNG favicons\r\n        const pngSizes = [\r\n            { name: \"favicon-16x16.png\", size: 16, include: generatePng.checked },\r\n            { name: \"favicon-32x32.png\", size: 32, include: generatePng.checked },\r\n            { name: \"favicon-48x48.png\", size: 48, include: generatePng.checked },\r\n            { name: \"favicon-64x64.png\", size: 64, include: generatePng.checked },\r\n            { name: \"apple-touch-icon.png\", size: 180, include: generateApple.checked },\r\n            { name: \"android-chrome-192x192.png\", size: 192, include: generateAndroid.checked },\r\n            { name: \"android-chrome-512x512.png\", size: 512, include: generateAndroid.checked }\r\n        ];\r\n        \r\n        \/\/ Generate each PNG favicon size\r\n        for (const item of pngSizes) {\r\n            if (!item.include) continue;\r\n            \r\n            downloadCanvas.width = item.size;\r\n            downloadCanvas.height = item.size;\r\n            downloadCtx.clearRect(0, 0, item.size, item.size);\r\n            downloadCtx.drawImage(processedImage, 0, 0, item.size, item.size);\r\n            \r\n            const blob = await new Promise(resolve => {\r\n                downloadCanvas.toBlob(resolve, 'image\/png', 0.9);\r\n            });\r\n            \r\n            if (blob) {\r\n                imgFolder.file(item.name, blob);\r\n            }\r\n        }\r\n        \r\n        \/\/ Generate ICO file if requested\r\n        if (generateIco.checked) {\r\n            const icoSizes = [16, 32, 48];\r\n            const icoCanvasArray = [];\r\n            \r\n            for (const size of icoSizes) {\r\n                downloadCanvas.width = size;\r\n                downloadCanvas.height = size;\r\n                downloadCtx.clearRect(0, 0, size, size);\r\n                downloadCtx.drawImage(processedImage, 0, 0, size, size);\r\n                \r\n                \/\/ Clone the canvas to avoid reference issues\r\n                const cloneCanvas = document.createElement('canvas');\r\n                cloneCanvas.width = size;\r\n                cloneCanvas.height = size;\r\n                cloneCanvas.getContext('2d').drawImage(downloadCanvas, 0, 0);\r\n                icoCanvasArray.push(cloneCanvas);\r\n            }\r\n            \r\n            try {\r\n                const icoBlob = await image2ico(icoCanvasArray);\r\n                if (icoBlob) {\r\n                    imgFolder.file(\"favicon.ico\", icoBlob);\r\n                }\r\n            } catch (icoError) {\r\n                console.warn(\"ICO generation warning:\", icoError);\r\n                \/\/ Continue without ICO if there's an error\r\n            }\r\n        }\r\n        \r\n        \/\/ Add HTML file\r\n        if (htmlCode.value) {\r\n            imgFolder.file(\"index.html\", htmlCode.value);\r\n        }\r\n        \r\n        \/\/ Add webmanifest if requested\r\n        if (generateWebmanifest.checked) {\r\n            const manifest = {\r\n                \"name\": \"My Website\",\r\n                \"short_name\": \"Website\",\r\n                \"icons\": [\r\n                    {\r\n                        \"src\": \"\/favicons\/android-chrome-192x192.png\",\r\n                        \"sizes\": \"192x192\",\r\n                        \"type\": \"image\/png\",\r\n                        \"include\": generateAndroid.checked\r\n                    },\r\n                    {\r\n                        \"src\": \"\/favicons\/android-chrome-512x512.png\",\r\n                        \"sizes\": \"512x512\",\r\n                        \"type\": \"image\/png\",\r\n                        \"include\": generateAndroid.checked\r\n                    }\r\n                ].filter(icon => icon.include),\r\n                \"theme_color\": backgroundColor.value,\r\n                \"background_color\": backgroundColor.value,\r\n                \"display\": \"standalone\"\r\n            };\r\n            \r\n            imgFolder.file(\"site.webmanifest\", JSON.stringify(manifest, null, 2));\r\n        }\r\n        \r\n        \/\/ Add README\r\n        imgFolder.file(\"README.txt\", `Favicon Package\\n===============\\n\\nInstructions...`);\r\n        \r\n        \/\/ Generate ZIP with progress monitoring\r\n        const content = await zip.generateAsync({\r\n            type: \"blob\",\r\n            compression: \"DEFLATE\",\r\n            compressionOptions: { level: 6 }\r\n        }, (metadata) => {\r\n            \/\/ Optional: Add progress feedback\r\n            console.log(`Progress: ${metadata.percent.toFixed(2)}%`);\r\n        });\r\n        \r\n        \/\/ Create download\r\n        const link = document.createElement('a');\r\n        link.href = URL.createObjectURL(content);\r\n        link.download = \"favicon-package.zip\";\r\n        document.body.appendChild(link);\r\n        link.click();\r\n        \r\n        \/\/ Cleanup\r\n        setTimeout(() => {\r\n            document.body.removeChild(link);\r\n            URL.revokeObjectURL(link.href);\r\n        }, 100);\r\n        \r\n    } catch (error) {\r\n        console.error(\"Download error details:\", error);\r\n        alert(`Download failed: ${error.message || 'Unknown error'}`);\r\n    } finally {\r\n        downloadBtn.disabled = false;\r\n        downloadBtn.innerHTML = '\ud83d\udce6 Download All';\r\n    }\r\n}\r\n  \r\n  \/\/ Reset upload\r\n  function resetUpload() {\r\n    originalImage = null;\r\n    processedImage = null;\r\n    imageUpload.value = '';\r\n    previewSection.style.display = 'none';\r\n    generateBtn.disabled = true;\r\n    downloadBtn.disabled = true;\r\n    htmlCodeSection.style.display = 'none';\r\n    \r\n    \/\/ Reset preview images\r\n    imagePreview.src = '';\r\n    favicon16.src = '';\r\n    favicon32.src = '';\r\n    favicon48.src = '';\r\n    favicon64.src = '';\r\n    favicon180.src = '';\r\n    favicon192.src = '';\r\n    favicon512.src = '';\r\n  }\r\n  \r\n  \/\/ Initialize\r\n  updateColorValue();\r\n  updatePaddingValue();\r\n});\r\n<\/script>\n\n\n\n<p><a href=\"https:\/\/ingenio.vip\/wp-admin\/admin.php?page=ingenio-tools-favicon-generator\"><\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>\ud83d\uddbc\ufe0f Favicon Generator Upload Your Image Drag &#038; drop your image here or click to browse Supports: JPG, PNG, SVG (Min 64\u00d764px) \ud83d\udd04 Change Image \ud83d\uddd1\ufe0f Reset Favicon Preview 16\u00d716 32\u00d732 48\u00d748 64\u00d764 180\u00d7180 192\u00d7192 512\u00d7512 \u2699\ufe0f Generation Options Generate ICO file (for legacy browsers) Generate PNG files (modern browsers) Generate Apple touch icons Generate [&hellip;]<\/p>\n<\/p><div class=\"more-link\"><a href=\"https:\/\/ingenio.vip\/zh\/tools-pages\/favicon-generator\/\" class=\"btn btn-small btn--dark btn-hover-shadow\"><span class=\"text\">Continue Reading<\/span><i class=\"seoicon-right-arrow\"><\/i><\/a><\/div>","protected":false},"author":1,"featured_media":0,"menu_order":0,"template":"elementor_header_footer","meta":{"_acf_changed":false,"googlesitekit_rrm_CAowrpbbCw:productID":"","footnotes":""},"tools-categories":[],"class_list":["post-4454","tools-pages","type-tools-pages","status-publish","hentry"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/ingenio.vip\/zh\/wp-json\/wp\/v2\/tools-pages\/4454","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ingenio.vip\/zh\/wp-json\/wp\/v2\/tools-pages"}],"about":[{"href":"https:\/\/ingenio.vip\/zh\/wp-json\/wp\/v2\/types\/tools-pages"}],"author":[{"embeddable":true,"href":"https:\/\/ingenio.vip\/zh\/wp-json\/wp\/v2\/users\/1"}],"version-history":[{"count":1,"href":"https:\/\/ingenio.vip\/zh\/wp-json\/wp\/v2\/tools-pages\/4454\/revisions"}],"predecessor-version":[{"id":4455,"href":"https:\/\/ingenio.vip\/zh\/wp-json\/wp\/v2\/tools-pages\/4454\/revisions\/4455"}],"wp:attachment":[{"href":"https:\/\/ingenio.vip\/zh\/wp-json\/wp\/v2\/media?parent=4454"}],"wp:term":[{"taxonomy":"tools-categories","embeddable":true,"href":"https:\/\/ingenio.vip\/zh\/wp-json\/wp\/v2\/tools-categories?post=4454"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}