首页
关于
友链
推荐
肥啾解析
百度一下
肥啾GPT
Search
1
宝塔面板登录 phpMyAdmin 提示服务器和客户端上指示的HTTPS之间不匹配
274 阅读
2
Customer complaints evolve with in-car tech
188 阅读
3
JavaScript解析
153 阅读
4
内连接,左连接,右连接作用及区别
112 阅读
5
所谓关系
109 阅读
默认分类
网游架设
手机游戏
python
PHP
Mysql
VBA
C++
JAVASCRIPT
javascript基础
Oracle
生产管理
计划控制
ERP系统开发
APS排产
MES研究
考勤系统
CPA
财管
实务
经济法
战略
审计
税法
藏书架
古典名著
世界名著
编程秘籍
攻防渗透
经管书籍
大佬传经
风雅读物
考试相关
心情格言
拾玉良言
外文报刊
外刊随选
Facebook
Twitter
China Daily
软考
登录
Search
标签搜索
期刊读物
古文
何瑜明
累计撰写
179
篇文章
累计收到
154
条评论
首页
栏目
默认分类
网游架设
手机游戏
python
PHP
Mysql
VBA
C++
JAVASCRIPT
javascript基础
Oracle
生产管理
计划控制
ERP系统开发
APS排产
MES研究
考勤系统
CPA
财管
实务
经济法
战略
审计
税法
藏书架
古典名著
世界名著
编程秘籍
攻防渗透
经管书籍
大佬传经
风雅读物
考试相关
心情格言
拾玉良言
外文报刊
外刊随选
Facebook
Twitter
China Daily
软考
页面
关于
友链
推荐
肥啾解析
百度一下
肥啾GPT
搜索到
179
篇与
的结果
2025-07-07
此内容被密码保护
加密文章,请前往内页查看详情
2025年07月07日
3 阅读
0 评论
0 点赞
2025-07-04
字符串核对
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>字符串比较工具</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background: linear-gradient(135deg, #8e8f93fc 100%, #8e8f93fc 100%); color: #333; min-height: 100vh; padding: 20px; display: flex; justify-content: center; align-items: center; } .container { width: 100%; max-width: 800px; background-color: white; border-radius: 15px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); overflow: hidden; } header { background: linear-gradient(to right, #514d4d, #514d4d); color: white; padding: 25px 30px; text-align: center; } h1 { font-size: 28px; margin-bottom: 8px; } .subtitle { font-size: 16px; opacity: 0.9; max-width: 600px; margin: 0 auto; } .content { padding: 30px; } .input-group { margin-bottom: 25px; } label { display: block; font-weight: 600; margin-bottom: 10px; color: #2c3e50; font-size: 18px; } textarea { width: 100%; height: 120px; padding: 15px; border: 2px solid #ddd; border-radius: 8px; font-size: 16px; resize: vertical; transition: border-color 0.3s; } textarea:focus { border-color: #3498db; outline: none; box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2); } .example { background-color: #f8f9fa; border-left: 4px solid #3498db; padding: 12px 15px; margin-top: 8px; border-radius: 0 4px 4px 0; font-size: 14px; } .example-title { font-weight: bold; margin-bottom: 5px; color: #2c3e50; } .actions { display: flex; justify-content: center; gap: 15px; margin-top: 20px; } button { padding: 14px 28px; font-size: 17px; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; } .compare-btn { background: linear-gradient(to right, #35c1a9, #35c1a9); color: white; flex: 1; } .clear-btn { background: #514d4d; color: white; } button:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); } button:active { transform: translateY(0); } .compare-btn:hover { background: linear-gradient(to right, #009a87, #85b536); } .clear-btn:hover { background: #c0392b; } .result-container { margin-top: 30px; padding: 25px; border-radius: 10px; display: none; } .result-title { font-size: 20px; font-weight: bold; margin-bottom: 15px; display: flex; align-items: center; } .result-content { padding: 15px; border-radius: 8px; margin-top: 10px; font-size: 16px; line-height: 1.6; } .success { background-color: rgba(46, 204, 113, 0.1); border: 1px solid #2ecc71; color: #27ae60; } .error { background-color: rgba(231, 76, 60, 0.1); border: 1px solid #e74c3c; color: #c0392b; } .icon { margin-right: 10px; font-size: 24px; } .requirements { background-color: #f8f9fa; border-radius: 10px; padding: 20px; margin-top: 25px; } .requirements h3 { color: #2c3e50; margin-bottom: 15px; display: flex; align-items: center; } .requirements ul { padding-left: 20px; } .requirements li { margin-bottom: 10px; line-height: 1.5; } footer { text-align: center; padding: 20px; color: #7f8c8d; font-size: 14px; border-top: 1px solid #eee; } @media (max-width: 600px) { .content { padding: 20px; } h1 { font-size: 24px; } .actions { flex-direction: column; } } </style> </head> <body> <div class="container"> <header> <h1>字符串比较工具</h1> <p class="subtitle">验证格式并比较两个字符串 - 检查第二个字符串是否是第一个字符串的子集</p> </header> <div class="content"> <div class="input-group"> <label for="str1">第一个字符串 (蓝本):</label> <textarea id="str1" placeholder="请输入第一个字符串,使用英文逗号分隔各项">3SV,实心胎(进口品牌),闪光警示灯,丰田样式悬浮座椅,高挂预滤器,高排气,VM330,3AP</textarea> </div> <div class="input-group"> <label for="str2">第二个字符串 (待比较):</label> <textarea id="str2" placeholder="请输入第二个字符串,使用英文逗号分隔各项">3SV,实心胎(进口品牌),闪光警示灯,丰田样式悬浮座椅,高挂预滤器,高排气</textarea> </div> <div class="actions"> <button class="compare-btn" onclick="compareStrings()"> <span class="icon">✓</span> 比较字符串 </button> <button class="clear-btn" onclick="clearInputs()"> <span class="icon">✕</span> 清空 </button> </div> <div id="result-container" class="result-container"> <div class="result-title"> <span class="icon" id="result-icon">?</span> <span id="result-title">结果</span> </div> <div id="result-content" class="result-content"></div> </div> <div class="requirements"> <h3>字符串要求</h3> <ul> <li>只能使用<strong>英文逗号</strong>作为分隔符(不允许中文逗号)</li> <li>字符串中<strong>不允许包含任何空格</strong></li> <li>第二个字符串必须是第一个字符串的<strong>子集</strong></li> <li>所有元素必须<strong>完全匹配</strong>(包括大小写和特殊字符)</li> <li>元素顺序<strong>不影响</strong>比较结果</li> </ul> </div> </div> </div> <script> function compareStrings() { const str1 = document.getElementById('str1').value.trim(); const str2 = document.getElementById('str2').value.trim(); const resultContainer = document.getElementById('result-container'); const resultContent = document.getElementById('result-content'); const resultTitle = document.getElementById('result-title'); const resultIcon = document.getElementById('result-icon'); // 清空之前的结果 resultContainer.style.display = 'none'; // 验证字符串1 const validation1 = validateString(str1, "第一个字符串"); if (!validation1.isValid) { showError(validation1.message, resultContainer, resultContent, resultTitle, resultIcon); return; } // 验证字符串2 const validation2 = validateString(str2, "第二个字符串"); if (!validation2.isValid) { showError(validation2.message, resultContainer, resultContent, resultTitle, resultIcon); return; } // 获取元素数组 const arr1 = str1.split(','); const arr2 = str2.split(','); // 检查第二个字符串是否是第一个字符串的子集 const missingElements = []; for (const element of arr2) { if (!arr1.includes(element)) { missingElements.push(element); } } // 检查结果并显示 if (missingElements.length === 0) { showSuccess("验证通过!第二个字符串是第一个字符串的子集。", resultContainer, resultContent, resultTitle, resultIcon); } else { showError(`第二个字符串包含第一个字符串中没有的元素:${missingElements.join(', ')}`, resultContainer, resultContent, resultTitle, resultIcon); } } function validateString(str, strName) { // 检查是否为空 if (str === '') { return { isValid: false, message: `${strName}不能为空!` }; } // 检查是否包含空格 if (/\s/.test(str)) { return { isValid: false, message: `${strName}包含空格!请移除所有空格。` }; } // 检查是否包含中文逗号 if (str.includes(',')) { return { isValid: false, message: `${strName}包含中文逗号!请使用英文逗号(,)。` }; } // 检查其他非法符号(只允许中文字符、英文字母、数字、英文逗号和括号) const illegalChars = str.match(/[^\u4e00-\u9fa5a-zA-Z0-9,()]/g); if (illegalChars && illegalChars.length > 0) { const uniqueChars = [...new Set(illegalChars)]; return { isValid: false, message: `${strName}包含非法字符:${uniqueChars.join('')}` }; } // 检查连续逗号或开头/结尾逗号 if (str.startsWith(',') || str.endsWith(',') || str.includes(',,')) { return { isValid: false, message: `${strName}格式错误:存在连续逗号或开头/结尾逗号` }; } return { isValid: true }; } function showError(message, container, content, title, icon) { container.style.display = 'block'; container.classList.remove('success'); container.classList.add('error'); content.innerHTML = message; title.textContent = '验证失败'; icon.textContent = '✕'; container.scrollIntoView({ behavior: 'smooth' }); } function showSuccess(message, container, content, title, icon) { container.style.display = 'block'; container.classList.remove('error'); container.classList.add('success'); content.innerHTML = message; title.textContent = '验证通过'; icon.textContent = '✓'; container.scrollIntoView({ behavior: 'smooth' }); } function clearInputs() { document.getElementById('str1').value = ''; document.getElementById('str2').value = ''; document.getElementById('result-container').style.display = 'none'; } </script> </body> </html>
2025年07月04日
6 阅读
0 评论
0 点赞
2025-07-03
此内容被密码保护
加密文章,请前往内页查看详情
2025年07月03日
1 阅读
0 评论
0 点赞
2025-06-26
图例管理
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>服务器图例管理系统</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } :root { --primary: #4361ee; --primary-dark: #3a56d4; --secondary: #3f37c9; --accent: #4895ef; --light: #f8f9fa; --dark: #212529; --gray: #6c757d; --light-gray: #e9ecef; --success: #4cc9f0; --warning: #f72585; --border-radius: 8px; --shadow: 0 4px 6px rgba(0, 0, 0, 0.1); --transition: all 0.3s ease; } body { background: linear-gradient(135deg, #f0f4f8 0%, #e2e8f0 100%); color: var(--dark); min-height: 100vh; padding: 20px; } .container { max-width: 1400px; margin: 0 auto; } /* 头部样式 */ header { background: white; border-radius: var(--border-radius); padding: 15px 25px; margin-bottom: 25px; box-shadow: var(--shadow); display: flex; align-items: center; flex-wrap: wrap; gap: 15px; } .logo { display: flex; align-items: center; font-size: 1.8rem; font-weight: bold; color: var(--primary); } .logo i { margin-right: 15px; font-size: 2.2rem; } .search-container { flex: 1; min-width: 300px; position: relative; } .search-container input { width: 100%; padding: 12px 15px 12px 45px; border-radius: 30px; border: 2px solid var(--light-gray); background: white; color: var(--dark); font-size: 1rem; transition: var(--transition); } .search-container input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.2); } .search-container i { position: absolute; left: 18px; top: 50%; transform: translateY(-50%); color: var(--gray); font-size: 1.2rem; } .header-controls { display: flex; gap: 15px; flex-wrap: wrap; } .btn { padding: 10px 20px; border-radius: 30px; border: none; background: var(--light); color: var(--dark); font-weight: 600; cursor: pointer; display: flex; align-items: center; gap: 8px; transition: var(--transition); box-shadow: var(--shadow); } .btn:hover { transform: translateY(-2px); box-shadow: 0 6px 10px rgba(0, 0, 0, 0.1); } .btn-primary { background: var(--primary); color: white; } .btn-primary:hover { background: var(--primary-dark); } /* 目录生成区 */ .directory-section { background: white; border-radius: var(--border-radius); padding: 25px; margin-bottom: 25px; box-shadow: var(--shadow); } .directory-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 15px; } .directory-header h2 { color: var(--dark); font-weight: 600; } .directory-controls { display: flex; gap: 15px; } .folder-info { display: flex; align-items: center; gap: 15px; background: var(--light); padding: 15px; border-radius: var(--border-radius); margin-bottom: 20px; } .folder-info i { color: var(--primary); font-size: 1.5rem; } .folder-details { flex: 1; } .folder-details h3 { margin-bottom: 5px; } .folder-details p { color: var(--gray); font-size: 0.9rem; } .directory-tree { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 15px; } .tree-category { background: var(--light); border-radius: var(--border-radius); padding: 15px; transition: var(--transition); cursor: pointer; } .tree-category:hover { background: rgba(67, 97, 238, 0.1); } .tree-category h3 { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; color: var(--primary); } .tree-category h3 i { font-size: 1.2rem; } .tree-items { padding-left: 25px; } .tree-item { padding: 8px 0; display: flex; align-items: center; gap: 8px; color: var(--gray); } .tree-item i { font-size: 0.9rem; color: var(--accent); } /* 图例展示区 */ .legends-section { background: white; border-radius: var(--border-radius); padding: 25px; box-shadow: var(--shadow); } .legends-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 15px; } .view-controls { display: flex; gap: 12px; } .view-btn { width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--light-gray); background: white; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: var(--transition); } .view-btn:hover, .view-btn.active { background: var(--primary); color: white; border-color: var(--primary); } .legend-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 25px; } .legend-card { background: white; border-radius: var(--border-radius); overflow: hidden; box-shadow: var(--shadow); transition: var(--transition); cursor: pointer; display: flex; flex-direction: column; border: 1px solid var(--light-gray); } .legend-card:hover { transform: translateY(-8px); box-shadow: 0 12px 20px rgba(0, 0, 0, 0.15); border-color: var(--accent); } .card-img { height: 180px; background: var(--light-gray); display: flex; align-items: center; justify-content: center; overflow: hidden; position: relative; } .card-img img { width: 100%; height: 100%; object-fit: cover; transition: var(--transition); } .legend-card:hover .card-img img { transform: scale(1.05); } .zoom-btn { position: absolute; bottom: 12px; right: 12px; width: 36px; height: 36px; border-radius: 50%; background: rgba(255, 255, 255, 0.9); color: var(--dark); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: var(--transition); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); } .zoom-btn:hover { background: var(--primary); color: white; transform: scale(1.1); } .card-content { padding: 18px; flex: 1; display: flex; flex-direction: column; } .card-content h4 { margin-bottom: 8px; font-weight: 600; color: var(--dark); } .card-content p { font-size: 0.9rem; color: var(--gray); line-height: 1.5; flex: 1; } .file-info { display: flex; justify-content: space-between; margin-top: 12px; font-size: 0.8rem; color: var(--gray); } /* 响应式设计 */ @media (max-width: 992px) { header { flex-direction: column; gap: 20px; } .search-container { min-width: 100%; margin: 0; } .header-controls { width: 100%; justify-content: center; } .directory-tree { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); } } @media (max-width: 768px) { .legend-grid { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); } .directory-tree { grid-template-columns: 1fr; } } @media (max-width: 480px) { .legend-grid { grid-template-columns: 1fr; } .header-controls { flex-direction: column; } .btn { width: 100%; justify-content: center; } .directory-controls { flex-direction: column; } } /* 大图模态框 */ .modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.9); z-index: 1000; justify-content: center; align-items: center; } .modal-content { max-width: 90%; max-height: 90%; position: relative; } .modal-content img { max-width: 100%; max-height: 80vh; border: 3px solid white; border-radius: 8px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); } .close-modal { position: absolute; top: 20px; right: 30px; color: white; font-size: 40px; cursor: pointer; transition: var(--transition); } .close-modal:hover { color: var(--accent); } .image-info { color: white; text-align: center; margin-top: 15px; font-size: 1.2rem; } /* 加载动画 */ .loader { display: flex; justify-content: center; padding: 40px 0; } .loader .spinner { width: 50px; height: 50px; border: 5px solid var(--light-gray); border-top: 5px solid var(--primary); border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /* 空状态 */ .empty-state { text-align: center; padding: 40px 0; color: var(--gray); grid-column: 1 / -1; } .empty-state i { font-size: 3rem; margin-bottom: 20px; opacity: 0.5; } .notification { position: fixed; bottom: 20px; right: 20px; background: var(--primary); color: white; padding: 15px 25px; border-radius: 8px; box-shadow: 0 5px 15px rgba(0,0,0,0.2); z-index: 1000; animation: fadeInOut 3s ease-in-out; display: none; } @keyframes fadeInOut { 0% { opacity: 0; transform: translateY(20px); } 10% { opacity: 1; transform: translateY(0); } 90% { opacity: 1; transform: translateY(0); } 100% { opacity: 0; transform: translateY(20px); } } </style> </head> <body> <div class="container"> <!-- 头部区域 --> <header> <div class="logo"> <i class="fas fa-map-marked-alt"></i> <span>服务器图例管理系统</span> </div> <div class="search-container"> <i class="fas fa-search"></i> <input type="text" id="searchInput" placeholder="搜索图例..."> </div> <div class="header-controls"> <button class="btn" id="refreshBtn"> <i class="fas fa-sync-alt"></i> 刷新图例 </button> <button class="btn btn-primary" id="generateCatalogBtn"> <i class="fas fa-folder-plus"></i> 生成目录 </button> </div> </header> <!-- 目录生成区 --> <section class="directory-section"> <div class="directory-header"> <h2><i class="fas fa-folder-tree"></i> 服务器图例目录</h2> <div class="directory-controls"> <div class="btn" id="expandAllBtn"> <i class="fas fa-expand"></i> 展开所有 </div> <div class="btn" id="collapseAllBtn"> <i class="fas fa-compress"></i> 折叠所有 </div> </div> </div> <div class="folder-info"> <i class="fas fa-folder-open"></i> <div class="folder-details"> <h3>服务器图片目录</h3> <p>路径: <span id="folderPath">./img</span> | 最后更新: <span id="lastUpdate">正在获取...</span></p> </div> </div> <div class="directory-tree" id="directoryTree"> <div class="loader"> <div class="spinner"></div> </div> </div> </section> <!-- 图例展示区 --> <section class="legends-section"> <div class="legends-header"> <h2><i class="fas fa-images"></i> 图例展示 (<span id="imageCount">0</span> 个图例)</h2> <div class="view-controls"> <div class="view-btn active" title="网格视图"> <i class="fas fa-th"></i> </div> <div class="view-btn" title="列表视图"> <i class="fas fa-list"></i> </div> <div class="view-btn" title="放大"> <i class="fas fa-search-plus"></i> </div> <div class="view-btn" title="缩小"> <i class="fas fa-search-minus"></i> </div> </div> </div> <div class="legend-grid" id="legendGrid"> <div class="loader"> <div class="spinner"></div> </div> </div> </section> </div> <!-- 大图模态框 --> <div class="modal" id="imageModal"> <span class="close-modal" id="closeModal">×</span> <div class="modal-content"> <img id="modalImage" src="" alt="大图预览"> <div class="image-info" id="imageInfo"></div> </div> </div> <!-- 通知区域 --> <div class="notification" id="notification"></div> <script> // 获取服务器图片的函数 async function getServerImages() { try { // 显示加载状态 document.getElementById('legendGrid').innerHTML = ` <div class="loader"> <div class="spinner"></div> </div> `; // 调用后端API获取图片数据 const response = await fetch('get_images.php'); if (!response.ok) { throw new Error('获取图片数据失败'); } const data = await response.json(); // 更新最后更新时间 document.getElementById('lastUpdate').textContent = data.last_updated; // 更新图片数量 document.getElementById('imageCount').textContent = data.images.length; // 渲染图片到页面 renderImages(data.images); // 生成目录树 generateDirectoryTree(data.categories); // 显示文件夹路径 document.getElementById('folderPath').textContent = data.folder_path; } catch (error) { console.error('获取图片数据时出错:', error); document.getElementById('legendGrid').innerHTML = ` <div class="empty-state"> <i class="fas fa-exclamation-triangle"></i> <h3>无法加载图片</h3> <p>${error.message}</p> <button class="btn" id="retryBtn" style="margin-top: 15px;"> <i class="fas fa-redo"></i> 重试 </button> </div> `; document.getElementById('retryBtn').addEventListener('click', getServerImages); } } // 渲染图片到页面 function renderImages(images) { const grid = document.getElementById('legendGrid'); if (images.length === 0) { grid.innerHTML = ` <div class="empty-state"> <i class="fas fa-folder-open"></i> <h3>没有找到图片</h3> <p>请检查服务器上的图片文件夹</p> </div> `; return; } grid.innerHTML = ''; images.forEach(image => { const card = document.createElement('div'); card.className = 'legend-card'; card.innerHTML = ` <div class="card-img"> <img src="${image.path}" alt="${image.name}"> <div class="zoom-btn" data-image="${image.path}" data-name="${image.name}"> <i class="fas fa-search-plus"></i> </div> </div> <div class="card-content"> <h4>${image.name}</h4> <p>${image.description}</p> <div class="file-info"> <span>${image.size}</span> <span>${image.date}</span> </div> </div> `; grid.appendChild(card); }); // 绑定放大按钮事件 document.querySelectorAll('.zoom-btn').forEach(btn => { btn.addEventListener('click', function(e) { e.stopPropagation(); const imageUrl = this.getAttribute('data-image'); const imageName = this.getAttribute('data-name'); showImageModal(imageUrl, imageName); }); }); } // 生成目录树 function generateDirectoryTree(categories) { const treeContainer = document.getElementById('directoryTree'); if (!categories || categories.length === 0) { treeContainer.innerHTML = ` <div class="empty-state"> <i class="fas fa-exclamation-circle"></i> <h3>没有目录数据</h3> <p>点击"生成目录"按钮创建目录</p> </div> `; return; } treeContainer.innerHTML = ''; categories.forEach(category => { const categoryElement = document.createElement('div'); categoryElement.className = 'tree-category'; categoryElement.innerHTML = ` <h3><i class="${category.icon}"></i> ${category.name} (${category.count})</h3> <div class="tree-items"> ${category.items.map(item => ` <div class="tree-item"> <i class="fas fa-file-image"></i> ${item} </div> `).join('')} </div> `; treeContainer.appendChild(categoryElement); }); } // 显示大图模态框 function showImageModal(imageUrl, imageName) { const modal = document.getElementById('imageModal'); const modalImg = document.getElementById('modalImage'); const imageInfo = document.getElementById('imageInfo'); modalImg.src = imageUrl; modalImg.alt = imageName; imageInfo.textContent = imageName; modal.style.display = 'flex'; } // 显示通知 function showNotification(message) { const notification = document.getElementById('notification'); notification.textContent = message; notification.style.display = 'block'; setTimeout(() => { notification.style.display = 'none'; }, 3000); } // 页面加载完成后初始化 document.addEventListener('DOMContentLoaded', function() { // 加载服务器图片 getServerImages(); // 刷新按钮事件 document.getElementById('refreshBtn').addEventListener('click', getServerImages); // 生成目录按钮事件 document.getElementById('generateCatalogBtn').addEventListener('click', function() { // 在实际应用中,这里会调用后端生成目录的API showNotification('目录已重新生成!'); // 模拟重新加载数据 setTimeout(() => { getServerImages(); }, 1000); }); // 关闭模态框 document.getElementById('closeModal').addEventListener('click', function() { document.getElementById('imageModal').style.display = 'none'; }); // 搜索功能 document.getElementById('searchInput').addEventListener('input', function(e) { const searchTerm = e.target.value.toLowerCase(); filterLegends(searchTerm); }); // 展开所有目录 document.getElementById('expandAllBtn').addEventListener('click', function() { // 实际应用中应展开所有目录项 showNotification('已展开所有目录'); }); // 折叠所有目录 document.getElementById('collapseAllBtn').addEventListener('click', function() { // 实际应用中应折叠所有目录项 showNotification('已折叠所有目录'); }); }); // 过滤图例 function filterLegends(searchTerm) { const cards = document.querySelectorAll('.legend-card'); let visibleCount = 0; cards.forEach(card => { const title = card.querySelector('h4').textContent.toLowerCase(); const description = card.querySelector('p').textContent.toLowerCase(); if (title.includes(searchTerm) || description.includes(searchTerm)) { card.style.display = ''; visibleCount++; } else { card.style.display = 'none'; } }); // 更新计数 document.getElementById('imageCount').textContent = visibleCount; } </script> </body> </html><?php // 设置响应头为JSON格式 header('Content-Type: application/json'); // 图片文件夹路径(相对于此PHP文件的路径) $imgFolder = './img'; // 获取最后更新时间 $lastUpdated = date("Y-m-d H:i:s", filemtime($imgFolder)); // 获取文件夹路径 $folderPath = realpath($imgFolder); // 扫描文件夹获取图片文件 $imageFiles = []; $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; if (is_dir($imgFolder)) { $files = scandir($imgFolder); foreach ($files as $file) { if ($file != '.' && $file != '..') { $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION)); if (in_array($extension, $allowedExtensions)) { $imageFiles[] = $file; } } } } // 构建图片数据 $images = []; foreach ($imageFiles as $index => $file) { $filePath = $imgFolder . '/' . $file; $fileSize = filesize($filePath); $fileDate = date("Y-m-d", filemtime($filePath)); // 生成友好的文件大小显示 $sizeFormatted = formatFileSize($fileSize); // 获取不带扩展名的文件名 $fileName = pathinfo($file, PATHINFO_FILENAME); $images[] = [ 'id' => $index + 1, 'name' => $fileName, 'path' => $filePath, 'description' => getDescription($fileName), 'size' => $sizeFormatted, 'date' => $fileDate, 'category' => getCategory($fileName) ]; } // 生成目录结构 $categories = [ [ 'name' => '地形地貌', 'icon' => 'fas fa-mountain', 'count' => count(array_filter($images, function($img) { return strpos($img['category'], '地形地貌') !== false; })), 'items' => ['地形等高线', '地貌分类', '高程图'] ], [ 'name' => '交通网络', 'icon' => 'fas fa-road', 'count' => count(array_filter($images, function($img) { return strpos($img['category'], '交通网络') !== false; })), 'items' => ['主要公路', '铁路网络', '机场位置'] ], [ 'name' => '自然地理', 'icon' => 'fas fa-water', 'count' => count(array_filter($images, function($img) { return strpos($img['category'], '自然地理') !== false; })), 'items' => ['水系分布', '地质构造', '土壤类型'] ], [ 'name' => '植被生态', 'icon' => 'fas fa-tree', 'count' => count(array_filter($images, function($img) { return strpos($img['category'], '植被生态') !== false; })), 'items' => ['森林覆盖', '草地分布', '植被类型'] ], [ 'name' => '人文地理', 'icon' => 'fas fa-city', 'count' => count(array_filter($images, function($img) { return strpos($img['category'], '人文地理') !== false; })), 'items' => ['城市区域', '工业区域', '居民点分布'] ] ]; // 构建响应数据 $response = [ 'status' => 'success', 'folder_path' => $folderPath, 'last_updated' => $lastUpdated, 'image_count' => count($images), 'images' => $images, 'categories' => $categories ]; // 输出JSON响应 echo json_encode($response); // 辅助函数:格式化文件大小 function formatFileSize($bytes) { if ($bytes >= 1048576) { return round($bytes / 1048576, 1) . ' MB'; } elseif ($bytes >= 1024) { return round($bytes / 1024, 1) . ' KB'; } else { return $bytes . ' bytes'; } } // 辅助函数:根据文件名生成描述 function getDescription($fileName) { $descriptions = [ '地形等高线' => '用于表示地形高度的等高线系统,间隔20米', '主要公路' => '国家级和省级主要公路交通网络', '水系分布' => '河流、湖泊、水库等水系分布图例', '森林覆盖' => '森林、灌木林、草地的植被覆盖分类', '城市区域' => '城市建成区、开发区、居民点分布', '工业区域' => '工厂、矿山、工业园区等分布', '降雨量分布' => '年平均降雨量分布图例(毫米)', '农业用地' => '农田、果园、养殖区等农业用地分类' ]; return $descriptions[$fileName] ?? $fileName . ' 图例,用于地图制作和地理信息系统分析'; } // 辅助函数:根据文件名分配类别 function getCategory($fileName) { $categories = [ '地形等高线' => '地形地貌', '地貌分类' => '地形地貌', '主要公路' => '交通网络', '铁路网络' => '交通网络', '水系分布' => '自然地理', '森林覆盖' => '植被生态', '城市区域' => '人文地理', '工业区域' => '人文地理', '降雨量分布' => '气候气象', '农业用地' => '土地利用' ]; return $categories[$fileName] ?? '其他'; } ?>
2025年06月26日
4 阅读
0 评论
0 点赞
2025-06-23
抠图功能
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>智能抠图工具 - 一键去除背景</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%); min-height: 100vh; padding: 20px; display: flex; flex-direction: column; align-items: center; color: white; } .container { width: 100%; max-width: 1200px; padding: 20px; } header { text-align: center; margin-bottom: 30px; padding: 20px; animation: fadeIn 1s ease; } h1 { font-size: 2.5rem; margin-bottom: 10px; text-shadow: 0 2px 4px rgba(0,0,0,0.2); } .subtitle { font-size: 1.2rem; opacity: 0.9; max-width: 600px; margin: 0 auto; } .app-container { display: flex; flex-wrap: wrap; gap: 30px; background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); border-radius: 20px; padding: 30px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); } .upload-section { flex: 1; min-width: 300px; display: flex; flex-direction: column; gap: 20px; } .preview-section { flex: 1; min-width: 300px; display: flex; flex-direction: column; gap: 20px; } .section-title { font-size: 1.3rem; margin-bottom: 10px; display: flex; align-items: center; gap: 10px; } .section-title i { font-size: 1.5rem; } .drop-area { border: 3px dashed rgba(255, 255, 255, 0.5); border-radius: 15px; padding: 40px 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; cursor: pointer; transition: all 0.3s ease; background: rgba(255, 255, 255, 0.05); } .drop-area:hover, .drop-area.active { border-color: #fff; background: rgba(255, 255, 255, 0.1); } .drop-area i { font-size: 3rem; margin-bottom: 15px; color: rgba(255, 255, 255, 0.7); } .drop-area p { margin: 10px 0; } .file-input { display: none; } .btn { background: linear-gradient(45deg, #ff8a00, #ff2070); color: white; border: none; padding: 12px 25px; font-size: 1rem; border-radius: 50px; cursor: pointer; transition: all 0.3s ease; font-weight: 600; display: inline-flex; align-items: center; justify-content: center; gap: 8px; box-shadow: 0 4px 15px rgba(255, 138, 0, 0.3); } .btn:hover { transform: translateY(-3px); box-shadow: 0 7px 20px rgba(255, 138, 0, 0.4); } .btn:active { transform: translateY(0); } .btn-outline { background: transparent; border: 2px solid rgba(255, 255, 255, 0.5); box-shadow: none; } .btn-outline:hover { background: rgba(255, 255, 255, 0.1); } .preview-container { display: flex; flex-direction: column; gap: 20px; } .preview-box { position: relative; width: 100%; height: 250px; border-radius: 15px; overflow: hidden; background: rgba(0, 0, 0, 0.2); display: flex; align-items: center; justify-content: center; border: 2px solid rgba(255, 255, 255, 0.1); } .preview-box img, .preview-box canvas { max-width: 100%; max-height: 100%; display: none; } .preview-placeholder { text-align: center; color: rgba(255, 255, 255, 0.5); } .controls { display: flex; gap: 15px; flex-wrap: wrap; } .tolerance-control { flex: 1; min-width: 200px; } .tolerance-label { display: flex; justify-content: space-between; margin-bottom: 8px; } .slider { width: 100%; height: 10px; -webkit-appearance: none; background: rgba(255, 255, 255, 0.1); border-radius: 5px; outline: none; } .slider::-webkit-slider-thumb { -webkit-appearance: none; width: 20px; height: 20px; border-radius: 50%; background: #ff8a00; cursor: pointer; } .tolerance-value { background: rgba(255, 255, 255, 0.1); padding: 2px 10px; border-radius: 10px; min-width: 40px; text-align: center; } .result-actions { display: flex; gap: 15px; margin-top: 10px; } .info-box { background: rgba(0, 0, 0, 0.2); border-radius: 15px; padding: 20px; margin-top: 30px; font-size: 0.9rem; } .info-box h3 { margin-bottom: 15px; display: flex; align-items: center; gap: 10px; } .info-content { display: flex; flex-wrap: wrap; gap: 20px; } .info-item { flex: 1; min-width: 250px; } .info-item ul { padding-left: 20px; margin-top: 10px; } .info-item li { margin-bottom: 8px; } footer { text-align: center; margin-top: 40px; padding: 20px; color: rgba(255, 255, 255, 0.7); font-size: 0.9rem; } .loading { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); flex-direction: column; align-items: center; justify-content: center; z-index: 10; border-radius: 15px; } .spinner { width: 50px; height: 50px; border: 5px solid rgba(255, 255, 255, 0.3); border-radius: 50%; border-top: 5px solid #ff8a00; animation: spin 1s linear infinite; margin-bottom: 15px; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes fadeIn { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } .featured-examples { display: flex; gap: 20px; margin-top: 15px; justify-content: center; flex-wrap: wrap; } .example-item { width: 80px; height: 80px; border-radius: 10px; overflow: hidden; cursor: pointer; border: 2px solid rgba(255, 255, 255, 0.3); transition: all 0.3s ease; } .example-item:hover { transform: scale(1.05); border-color: white; } .example-item img { width: 100%; height: 100%; object-fit: cover; } @media (max-width: 768px) { .app-container { flex-direction: column; } .controls { flex-direction: column; } h1 { font-size: 2rem; } } </style> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> </head> <body> <div class="container"> <header> <h1><i class="fas fa-magic"></i> 智能抠图工具</h1> <p class="subtitle">上传图片,一键自动去除背景 - 无需复杂操作,快速获得透明背景PNG图片</p> </header> <div class="app-container"> <div class="upload-section"> <h2 class="section-title"><i class="fas fa-upload"></i> 上传图片</h2> <div class="drop-area" id="dropArea"> <i class="fas fa-cloud-upload-alt"></i> <p>拖放图片到此处或</p> <button class="btn" id="browseBtn"><i class="fas fa-folder-open"></i> 选择图片</button> <p class="small">支持 JPG, PNG 格式,最大 5MB</p> </div> <input type="file" id="fileInput" class="file-input" accept="image/*"> <div class="featured-examples"> <div class="example-item" data-example="1"> <img src="https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt="示例1"> </div> <div class="example-item" data-example="2"> <img src="https://images.unsplash.com/photo-1543852786-1cf6624b9987?ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt="示例2"> </div> <div class="example-item" data-example="3"> <img src="https://images.unsplash.com/photo-1533738363-b7f9aef128ce?ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt="示例3"> </div> <div class="example-item" data-example="4"> <img src="https://images.unsplash.com/photo-1526336024174-e58f5cdd8e13?ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt="示例4"> </div> </div> </div> <div class="preview-section"> <h2 class="section-title"><i class="fas fa-image"></i> 预览结果</h2> <div class="preview-container"> <div class="preview-box"> <div class="preview-placeholder"> <i class="fas fa-image" style="font-size: 3rem; margin-bottom: 15px;"></i> <p>处理后的图像将显示在这里</p> </div> <canvas id="originalCanvas"></canvas> <canvas id="resultCanvas"></canvas> <div class="loading" id="loading"> <div class="spinner"></div> <p>正在处理图像...</p> </div> </div> <div class="controls"> <div class="tolerance-control"> <div class="tolerance-label"> <span>抠图精度调节:</span> <span class="tolerance-value" id="toleranceValue">30</span> </div> <input type="range" min="1" max="100" value="30" class="slider" id="toleranceSlider"> <p style="font-size: 0.8rem; margin-top: 5px; opacity: 0.7;">值越小,抠图越精细(处理时间越长)</p> </div> <button class="btn" id="processBtn"><i class="fas fa-cogs"></i> 开始抠图</button> </div> <div class="result-actions"> <button class="btn" id="downloadBtn" disabled><i class="fas fa-download"></i> 下载结果</button> <button class="btn btn-outline" id="resetBtn"><i class="fas fa-redo"></i> 重置</button> </div> </div> </div> </div> <div class="info-box"> <h3><i class="fas fa-info-circle"></i> 使用说明</h3> <div class="info-content"> <div class="info-item"> <h4>如何获得最佳效果:</h4> <ul> <li>选择主体与背景对比度高的图片</li> <li>避免复杂背景或毛发等细节丰富的图像</li> <li>如果效果不理想,尝试调整抠图精度</li> <li>对于人像照片效果最佳</li> </ul> </div> <div class="info-item"> <h4>技术说明:</h4> <ul> <li>使用HTML5 Canvas实现纯前端处理</li> <li>基于智能颜色识别算法</li> <li>处理时间取决于图像大小和复杂度</li> <li>完全在浏览器中运行 - 不上传服务器</li> </ul> </div> </div> </div> </div> <footer> <p>© 2023 智能抠图工具 | 纯前端实现 | 无需上传服务器 | 保护您的隐私</p> </footer> <script> document.addEventListener('DOMContentLoaded', function() { // 获取DOM元素 const dropArea = document.getElementById('dropArea'); const fileInput = document.getElementById('fileInput'); const browseBtn = document.getElementById('browseBtn'); const processBtn = document.getElementById('processBtn'); const downloadBtn = document.getElementById('downloadBtn'); const resetBtn = document.getElementById('resetBtn'); const toleranceSlider = document.getElementById('toleranceSlider'); const toleranceValue = document.getElementById('toleranceValue'); const originalCanvas = document.getElementById('originalCanvas'); const resultCanvas = document.getElementById('resultCanvas'); const loading = document.getElementById('loading'); const previewPlaceholder = document.querySelector('.preview-placeholder'); let originalImage = null; let processedImage = null; // 设置事件监听器 browseBtn.addEventListener('click', () => fileInput.click()); fileInput.addEventListener('change', handleFileSelect); dropArea.addEventListener('dragover', handleDragOver); dropArea.addEventListener('dragleave', handleDragLeave); dropArea.addEventListener('drop', handleDrop); processBtn.addEventListener('click', processImage); downloadBtn.addEventListener('click', downloadResult); resetBtn.addEventListener('click', resetApp); toleranceSlider.addEventListener('input', updateTolerance); // 示例图片点击事件 document.querySelectorAll('.example-item').forEach(item => { item.addEventListener('click', function() { const exampleNum = this.getAttribute('data-example'); loadExample(exampleNum); }); }); // 更新容差值显示 function updateTolerance() { toleranceValue.textContent = toleranceSlider.value; } // 处理文件选择 function handleFileSelect(e) { const file = e.target.files[0]; if (file && file.type.match('image.*')) { loadImage(file); } } // 处理拖放 function handleDragOver(e) { e.preventDefault(); e.stopPropagation(); dropArea.classList.add('active'); } function handleDragLeave(e) { e.preventDefault(); e.stopPropagation(); dropArea.classList.remove('active'); } function handleDrop(e) { e.preventDefault(); e.stopPropagation(); dropArea.classList.remove('active'); const file = e.dataTransfer.files[0]; if (file && file.type.match('image.*')) { loadImage(file); } } // 加载图片 function loadImage(file) { const reader = new FileReader(); reader.onload = function(e) { originalImage = new Image(); originalImage.onload = function() { // 显示原始图片 displayOriginalImage(); processBtn.disabled = false; }; originalImage.src = e.target.result; }; reader.readAsDataURL(file); } // 加载示例图片 function loadExample(num) { const examples = { '1': 'https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80', '2': 'https://images.unsplash.com/photo-1543852786-1cf6624b9987?ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80', '3': 'https://images.unsplash.com/photo-1533738363-b7f9aef128ce?ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80', '4': 'https://images.unsplash.com/photo-1526336024174-e58f5cdd8e13?ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80' }; originalImage = new Image(); originalImage.crossOrigin = "Anonymous"; originalImage.onload = function() { displayOriginalImage(); processBtn.disabled = false; }; originalImage.src = examples[num]; } // 显示原始图片 function displayOriginalImage() { const previewBox = document.querySelector('.preview-box'); previewPlaceholder.style.display = 'none'; // 设置canvas尺寸 const maxWidth = previewBox.clientWidth - 20; const maxHeight = previewBox.clientHeight - 20; let width = originalImage.width; let height = originalImage.height; if (width > maxWidth) { height = (maxWidth / width) * height; width = maxWidth; } if (height > maxHeight) { width = (maxHeight / height) * width; height = maxHeight; } originalCanvas.width = width; originalCanvas.height = height; resultCanvas.width = width; resultCanvas.height = height; const ctx = originalCanvas.getContext('2d'); ctx.clearRect(0, 0, width, height); ctx.drawImage(originalImage, 0, 0, width, height); originalCanvas.style.display = 'block'; } // 处理图像(抠图) function processImage() { if (!originalImage) return; // 显示加载状态 loading.style.display = 'flex'; downloadBtn.disabled = true; // 使用setTimeout让UI有机会更新 setTimeout(() => { try { const tolerance = parseInt(toleranceSlider.value); removeBackground(tolerance); // 显示结果 originalCanvas.style.display = 'none'; resultCanvas.style.display = 'block'; downloadBtn.disabled = false; } catch (error) { console.error('Error processing image:', error); alert('处理图像时出错: ' + error.message); } finally { loading.style.display = 'none'; } }, 100); } // 移除背景的核心算法 function removeBackground(tolerance) { const ctx = originalCanvas.getContext('2d'); const resultCtx = resultCanvas.getContext('2d'); // 获取图像数据 const imageData = ctx.getImageData(0, 0, originalCanvas.width, originalCanvas.height); const data = imageData.data; // 创建新图像数据(带透明通道) const newData = new ImageData(originalCanvas.width, originalCanvas.height); const newPixels = newData.data; // 假设图片中心点属于前景 const centerX = Math.floor(originalCanvas.width / 2); const centerY = Math.floor(originalCanvas.height / 2); const centerIndex = (centerY * originalCanvas.width + centerX) * 4; // 获取中心点颜色作为前景参考 const centerR = data[centerIndex]; const centerG = data[centerIndex + 1]; const centerB = data[centerIndex + 2]; // 处理每个像素 for (let i = 0; i < data.length; i += 4) { const r = data[i]; const g = data[i + 1]; const b = data[i + 2]; // 计算与中心点的颜色差异 const diff = Math.sqrt( Math.pow(r - centerR, 2) + Math.pow(g - centerG, 2) + Math.pow(b - centerB, 2) ); // 如果颜色差异在容差范围内,保留像素,否则设为透明 if (diff < tolerance) { newPixels[i] = r; newPixels[i + 1] = g; newPixels[i + 2] = b; newPixels[i + 3] = 255; // 不透明 } else { newPixels[i] = 0; newPixels[i + 1] = 0; newPixels[i + 2] = 0; newPixels[i + 3] = 0; // 完全透明 } } // 将新图像数据绘制到结果canvas resultCtx.putImageData(newData, 0, 0); } // 下载结果 function downloadResult() { if (!resultCanvas) return; const link = document.createElement('a'); link.download = '抠图结果.png'; link.href = resultCanvas.toDataURL('image/png'); link.click(); } // 重置应用 function resetApp() { // 重置所有状态 originalImage = null; processedImage = null; // 隐藏canvas originalCanvas.style.display = 'none'; resultCanvas.style.display = 'none'; // 显示占位符 previewPlaceholder.style.display = 'flex'; // 重置按钮状态 processBtn.disabled = true; downloadBtn.disabled = true; // 重置文件输入 fileInput.value = ''; } // 初始化 updateTolerance(); }); </script> </body> </html>
2025年06月23日
3 阅读
0 评论
0 点赞
1
...
14
15
16
...
36
0:00