登录 注册

 设计一张图片转换和压缩的html的漂亮图片,兼容手机

2025-10-19  回复(0) 

好的,我将为你设计一个漂亮且兼容手机的图片转换和压缩 HTML 页面。

核心设计理念:

* 简洁直观: 用户应该能够快速理解如何使用。
* 现代化 UI: 使用扁平化、卡片式设计,搭配柔和的色彩和清晰的图标。
* 响应式布局: 确保在不同尺寸的设备上都有良好的视觉效果和用户体验。
* 交互反馈: 当用户进行上传、转换或下载操作时,提供清晰的视觉反馈。
* 性能优化: 尽量减少页面加载时间和图片处理的等待时间。

HTML 结构(index.html

html
<!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="style.css">
<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 class="header">
<h1><i class="fas fa-images"></i> 图片处理工具</h1>
<p>轻松转换图片格式,智能压缩图片大小</p>
</header>

<main class="main-content">
<section class="upload-section card">
<h2>上传你的图片</h2>
<div class="drop-zone">
<div class="drop-zone-text">
<i class="fas fa-cloud-upload-alt"></i>
<p>拖拽图片到这里,或点击选择文件</p>
<input type="file" id="file-upload" accept="image/*" multiple hidden>
<button class="btn-primary" onclick="document.getElementById('file-upload').click()">选择文件</button>
</div>
</div>
<div id="file-list">
<!-- 这里会动态显示已上传的文件 -->
</div>
</section>

<section class="options-section card">
<h2>处理选项</h2>
<div class="options-group">
<label for="output-format">输出格式:</label>
<select id="output-format">
<option value="jpeg">JPEG</option>
<option value="png">PNG</option>
<option value="webp">WEBP</option>
<option value="gif">GIF</option>
</select>
</div>
<div class="options-group">
<label for="compression-level">压缩质量 (0-100):</label>
<input type="range" id="compression-level" min="0" max="100" value="75">
<span id="compression-value">75</span>%
</div>
<div class="options-group">
<label for="resize-width">宽度 (像素):</label>
<input type="number" id="resize-width" min="1" placeholder="保持原比例">
<label for="resize-height">高度 (像素):</label>
<input type="number" id="resize-height" min="1" placeholder="保持原比例">
<button id="clear-resize" class="btn-secondary">清除尺寸</button>
</div>
</section>

<section class="action-section">
<button id="process-images" class="btn-primary btn-large"><i class="fas fa-cog"></i> 开始处理</button>
</section>

<section id="output-section" class="output-section card" style="display: none;">
<h2>处理结果</h2>
<div id="processed-images-preview">
<!-- 这里会显示处理后的图片预览和下载按钮 -->
</div>
<button id="download-all" class="btn-secondary" style="display: none;"><i class="fas fa-download"></i> 全部下载</button>
</section>
</main>

<footer class="footer">
<p>© 2023 图片处理工具. 保留所有权利.</p>
</footer>
</div>

<script src="script.js"></script>
</body>
</html>


CSS 样式(style.css

css
/* 全局样式 */
:root {
--primary-color: #4CAF50; /* 绿色系 */
--secondary-color: #00BCD4; /* 青色系 */
--background-color: #f4f7f6;
--card-background: #ffffff;
--text-color: #333;
--border-color: #e0e0e0;
--shadow-color: rgba(0, 0, 0, 0.1);
--hover-shadow: rgba(0, 0, 0, 0.15);
}

body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
background-color: var(--background-color);
color: var(--text-color);
display: flex;
justify-content: center;
align-items: flex-start; /* 顶部对齐 */
min-height: 100vh;
box-sizing: border-box;
}

.container {
width: 100%;
max-width: 960px; /* 限制最大宽度 */
padding: 20px;
box-sizing: border-box;
}

/* 头部 */
.header {
text-align: center;
margin-bottom: 40px;
padding: 20px;
background-color: var(--card-background);
border-radius: 8px;
box-shadow: 0 4px 10px var(--shadow-color);
}

.header h1 {
color: var(--primary-color);
margin-bottom: 10px;
font-size: 2.5em;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}

.header p {
font-size: 1.1em;
color: #666;
}

/* 卡片样式 */
.card {
background-color: var(--card-background);
border-radius: 10px;
box-shadow: 0 4px 15px var(--shadow-color);
margin-bottom: 30px;
padding: 30px;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 25px var(--hover-shadow);
}

.card h2 {
text-align: center;
margin-top: 0;
margin-bottom: 25px;
color: var(--primary-color);
font-size: 1.8em;
}

/* 主要内容区域 */
.main-content {
width: 100%;
}

/* 上传区域 */
.upload-section .drop-zone {
border: 3px dashed var(--border-color);
border-radius: 8px;
padding: 40px;
text-align: center;
color: #999;
cursor: pointer;
transition: border-color 0.3s ease, background-color 0.3s ease;
margin-bottom: 20px;
}

.upload-section .drop-zone:hover {
border-color: var(--primary-color);
background-color: #f9f9f9;
}

.drop-zone-text i {
font-size: 3em;
margin-bottom: 15px;
color: var(--secondary-color);
}

.drop-zone-text p {
font-size: 1.1em;
margin-bottom: 20px;
}

#file-list {
margin-top: 20px;
max-height: 200px; /* 限制高度,溢出滚动 */
overflow-y: auto;
padding-right: 10px; /* 为滚动条留空间 */
}

#file-list div {
background-color: var(--background-color);
padding: 12px 15px;
margin-bottom: 8px;
border-radius: 5px;
display: flex;
justify-content: space-between;
align-items: center;
border: 1px solid var(--border-color);
font-size: 0.95em;
}

#file-list .file-info {
display: flex;
align-items: center;
gap: 10px;
}

#file-list .file-info i {
color: var(--secondary-color);
}

#file-list .file-actions button {
background: none;
border: none;
color: #ccc;
cursor: pointer;
font-size: 1.2em;
transition: color 0.3s ease;
}

#file-list .file-actions button:hover {
color: #f44336; /* 红色 */
}


/* 选项区域 */
.options-section .options-group {
margin-bottom: 20px;
display: flex;
flex-wrap: wrap; /* 允许换行 */
align-items: center;
gap: 15px;
}

.options-section label {
font-weight: bold;
min-width: 150px; /* 保证标签宽度一致 */
flex-shrink: 0; /* 不允许缩小 */
}

.options-section select,
.options-section input[type="number"],
.options-section input[type="range"] {
padding: 10px 12px;
border: 1px solid var(--border-color);
border-radius: 5px;
font-size: 1em;
transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.options-section input[type="number"] {
width: 100px; /* 宽度固定 */
}

.options-section input[type="range"] {
flex-grow: 1; /* 允许范围滑块增长 */
cursor: pointer;
}

.options-section input[type="range"]:focus,
.options-section select:focus,
.options-section input[type="number"]:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.3);
}

/* 按钮样式 */
.btn-primary {
background-color: var(--primary-color);
color: white;
padding: 12px 25px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 1.1em;
transition: background-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
display: inline-flex;
align-items: center;
gap: 8px;
font-weight: bold;
}

.btn-primary:hover {
background-color: #388E3C; /* 深一点的绿色 */
transform: translateY(-2px);
box-shadow: 0 4px 10px var(--shadow-color);
}

.btn-secondary {
background-color: var(--secondary-color);
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 1em;
transition: background-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
display: inline-flex;
align-items: center;
gap: 8px;
}

.btn-secondary:hover {
background-color: #0097A7; /* 深一点的青色 */
transform: translateY(-2px);
box-shadow: 0 4px 10px var(--shadow-color);
}

.btn-large {
padding: 15px 30px;
font-size: 1.3em;
}

.action-section {
text-align: center;
margin-top: 40px;
margin-bottom: 40px;
}

/* 输出区域 */
.output-section h2 {
color: var(--secondary-color);
}

#processed-images-preview {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* 响应式网格 */
gap: 20px;
margin-top: 20px;
}

.processed-image-item {
background-color: var(--card-background);
border-radius: 8px;
box-shadow: 0 2px 8px var(--shadow-color);
text-align: center;
padding: 15px;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.processed-image-item:hover {
transform: translateY(-3px);
box-shadow: 0 4px 12px var(--shadow-color);
}

.processed-image-item img {
max-width: 100%;
height: 200px; /* 固定预览高度 */
object-fit: contain; /* 保持图片比例 */
border-radius: 5px;
margin-bottom: 15px;
background-color: var(--background-color); /* 为透明背景的图片提供背景 */
}

.processed-image-item p {
font-size: 0.9em;
color: #555;
margin-bottom: 10px;
word-break: break-all; /* 防止长文件名溢出 */
}

.processed-image-item .btn-download-single {
background-color: var(--primary-color);
color: white;
padding: 8px 15px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 0.9em;
transition: background-color 0.3s ease, transform 0.3s ease;
display: inline-flex;
align-items: center;
gap: 5px;
}

.processed-image-item .btn-download-single:hover {
background-color: #388E3C;
transform: translateY(-1px);
}

#download-all {
display: block; /* 块级元素,方便居中 */
margin: 30px auto 0; /* 上下边距,左右自动居中 */
}

/* 页脚 */
.footer {
text-align: center;
margin-top: 50px;
padding: 20px;
color: #888;
font-size: 0.9em;
}

/* 响应式设计 */
@media (max-width: 768px) {
.container {
padding: 15px;
}

.header h1 {
font-size: 1.8em;
}

.header p {
font-size: 1em;
}

.card {
padding: 20px;
}

.card h2 {
font-size: 1.5em;
}

.upload-section .drop-zone {
padding: 30px;
}

.drop-zone-text p {
font-size: 1em;
}

.options-section .options-group {
flex-direction: column; /* 堆叠排列 */
align-items: flex-start; /* 左对齐 */
}

.options-section label {
min-width: auto; /* 宽度自适应 */
margin-bottom: 5px;
}

.options-section input[type="number"],
.options-section select {
width: 100%; /* 宽度占满 */
box-sizing: border-box; /* 包含 padding 和 border */
}

.btn-primary, .btn-secondary, .btn-large {
width: 100%; /* 按钮占满 */
justify-content: center;
box-sizing: border-box;
}

#processed-images-preview {
grid-template-columns: 1fr; /* 单列布局 */
}

.processed-image-item img {
height: 180px;
}
}

@media (max-width: 480px) {
.header h1 {
font-size: 1.5em;
}

.header p {
font-size: 0.9em;
}

.card {
padding: 15px;
}

.card h2 {
font-size: 1.3em;
}

.drop-zone-text i {
font-size: 2.5em;
}

.btn-primary, .btn-secondary {
font-size: 1em;
}

.btn-large {
font-size: 1.2em;
}
}


JavaScript 交互(script.js

* 文件上传和拖拽: 实现文件选择和拖拽上传功能。
* 文件列表显示: 动态显示已选择的文件信息(文件名、大小)。
* 选项控制: 响应滑块、下拉框和输入框的变化。
* 图片处理(示例):
* 核心功能: 这里需要一个图片的 Canvas API 或者 Web Worker 来实现实际的图片转换(格式、压缩、尺寸调整)。
* 前端实现复杂性: 由于纯前端图片处理(尤其是效率和格式支持)有一定的复杂性,一个完整的解决方案可能需要使用如 browser-image-compression 库,或者更复杂的 Canvas 操作。
* 以下提供一个简化的结构,你需要在此基础上集成具体的图片处理逻辑。
* 预览和下载: 显示处理后的图片预览,并提供单独下载或全部下载的按钮。

javascript
document.addEventListener('DOMContentLoaded', () => {
const fileUploadInput = document.getElementById('file-upload');
const dropZone = document.querySelector('.drop-zone');
const fileListDiv = document.getElementById('file-list');
const processButton = document.getElementById('process-images');
const outputSection = document.getElementById('output-section');
const processedImagesPreview = document.getElementById('processed-images-preview');
const downloadAllButton = document.getElementById('download-all');
const compressionLevelInput = document.getElementById('compression-level');
const compressionValueSpan = document.getElementById('compression-value');
const resizeWidthInput = document.getElementById('resize-width');
const resizeHeightInput = document.getElementById('resize-height');
const clearResizeButton = document.getElementById('clear-resize');

let selectedFiles = []; // 存储选中的文件对象

// --- 文件上传和拖拽 ---
dropZone.addEventListener('click', () => {
fileUploadInput.click();
});

fileUploadInput.addEventListener('change', (e) => {
handleFiles(e.target.files);
e.target.value = ''; // 清空 input value,以便可以重新选择相同文件
});

dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.style.borderColor = '#4CAF50';
dropZone.style.backgroundColor = '#e8f5e9';
});

dropZone.addEventListener('dragleave', () => {
dropZone.style.borderColor = '#e0e0e0';
dropZone.style.backgroundColor = 'transparent';
});

dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.style.borderColor = '#e0e0e0';
dropZone.style.backgroundColor = 'transparent';
handleFiles(e.dataTransfer.files);
});

function handleFiles(files) {
for (const file of files) {
if (!file.type.startsWith('image/')) {
alert(`文件 "${file.name}" 不是有效的图片文件,已跳过。`);
continue;
}
// 避免重复添加
if (!selectedFiles.some(f => f.name === file.name)) {
selectedFiles.push(file);
renderFileList();
}
}
}

function renderFileList() {
fileListDiv.innerHTML = '';
selectedFiles.forEach((file, index) => {
const fileElement = document.createElement('div');
fileElement.innerHTML = `
<div class="file-info">
<i class="fas fa-image"></i>
<span>${file.name}</span>
</div>
<div class="file-actions">
<button onclick="removeFile(${index})"><i class="fas fa-times-circle"></i></button>
</div>
`;
fileListDiv.appendChild(fileElement);
});
// 显示处理按钮(如果之前隐藏了)
if (selectedFiles.length > 0) {
processButton.style.display = 'inline-flex';
} else {
processButton.style.display = 'none';
}
}

// 移除文件函数 (全局可访问,供 onclick 调用)
window.removeFile = function(index) {
selectedFiles.splice(index, 1);
renderFileList();
// 如果没有文件了,隐藏结果区
if (selectedFiles.length === 0) {
outputSection.style.display = 'none';
}
};

// --- 选项控制 ---
compressionLevelInput.addEventListener('input', () => {
compressionValueSpan.textContent = compressionLevelInput.value;
});

clearResizeButton.addEventListener('click', () => {
resizeWidthInput.value = '';
resizeHeightInput.value = '';
});

// --- 图片处理 ---
processButton.addEventListener('click', async () => {
if (selectedFiles.length === 0) {
alert('请先选择要处理的图片!');
return;
}

outputSection.style.display = 'block';
processedImagesPreview.innerHTML = '<p>正在处理中,请稍候...</p>';
downloadAllButton.style.display = 'none'; // 隐藏旧的下载按钮

const outputFormat = document.getElementById('output-format').value;
const compressionLevel = parseInt(compressionLevelInput.value) / 100; // 0-1 范围
const targetWidth = resizeWidthInput.value ? parseInt(resizeWidthInput.value) : null;
const targetHeight = resizeHeightInput.value ? parseInt(resizeHeightInput.value) : null;

const processedResults = [];

for (const file of selectedFiles) {
try {
const processedBlob = await processImage(file, outputFormat, compressionLevel, targetWidth, targetHeight);
processedResults.push({ blob: processedBlob, filename: file.name, format: outputFormat });
addProcessedImagePreview(processedBlob, file.name, outputFormat, processedResults.length - 1);
} catch (error) {
console.error('图片处理失败:', error);
processedImagesPreview.innerHTML += <p style="color: red;">处理文件 "${file.name}" 时出错: ${error.message}</p>;
}
}

if (processedResults.length > 0) {
downloadAllButton.style.display = 'inline-flex';
downloadAllButton.onclick = () => downloadAllImages(processedResults);
} else {
processedImagesPreview.innerHTML = '<p>所有文件处理均未成功。</p>';
}
});

// 实际的图片处理函数 (需要集成 Canvas API 或库)
async function processImage(file, outputFormat, compressionLevel, targetWidth, targetHeight) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = async (event) => {
const img = new Image();
img.onload = async () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');

// 1. 尺寸调整 (如果提供了宽度或高度)
let newWidth = img.width;
let newHeight = img.height;

if (targetWidth !== null || targetHeight !== null) {
if (targetWidth !== null && targetHeight !== null) {
// 同时指定宽高
newWidth = targetWidth;
newHeight = targetHeight;
} else if (targetWidth !== null) {
// 只指定宽度,按比例计算高度
newWidth = targetWidth;
newHeight = img.height * (targetWidth / img.width);
} else if (targetHeight !== null) {
// 只指定高度,按比例计算宽度
newHeight = targetHeight;
newWidth = img.width * (targetHeight / img.height);
}
canvas.width = newWidth;
canvas.height = newHeight;
ctx.drawImage(img, 0, 0, newWidth, newHeight);
} else {
// 未指定尺寸,使用原图尺寸
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
}

// 2. 格式转换与压缩
let mimeType = `image/${outputFormat}`;
let quality = compressionLevel;

// 对于 PNG 和 GIF,质量参数不适用或效果有限,但仍然可以设置
if (outputFormat === 'png' || outputFormat === 'gif') {
// PNG 压缩通常是无损的,quality 参数影响不大
// GIF 格式处理更复杂,这里仅做简单导出
quality = 0.9; // 留一个默认值,如果需要更精细的控制
} else if (outputFormat === 'jpeg') {
// JPEG 质量参数是 0-1
quality = compressionLevel;
} else if (outputFormat === 'webp') {
// WEBP 也可以设置质量
quality = compressionLevel;
} else {
// 默认 JPEG 导出
mimeType = 'image/jpeg';
quality = compressionLevel;
}

canvas.toBlob(async (blob) => {
if (blob) {
resolve(blob);
} else {
reject(new Error('Canvas toBlob 失败'));
}
}, mimeType, quality);
};
img.onerror = (err) => reject(err);
img.src = event.target.result;
};
reader.onerror = (err) => reject(err);
reader.readAsDataURL(file); // 读取为 Data URL
});
}

function addProcessedImagePreview(blob, originalFilename, outputFormat, index) {
const reader = new FileReader();
reader.onload = (e) => {
const previewDiv = document.createElement('div');
previewDiv.classList.add('processed-image-item');
const newFilename = `${originalFilename.replace(/\.[^/.]+$/, '')}.${outputFormat}`;
previewDiv.innerHTML = `
<img src="${e.target.result}" alt="Processed Image">
<p>${newFilename}</p>
<button class="btn-download-single" onclick="downloadSingleImage('${e.target.result}', '${newFilename}')"><i class="fas fa-download"></i> 下载</button>
`;
processedImagesPreview.appendChild(previewDiv);
};
reader.readAsDataURL(blob);
}

// 下载单个图片函数 (全局可访问)
window.downloadSingleImage = function(dataUrl, filename) {
const link = document.createElement('a');
link.href = dataUrl;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};

// 全部下载函数
function downloadAllImages(results) {
const zip = new JSZip(); // 需要引入 JSZip 库
results.forEach(item => {
zip.file(`${item.filename.replace(/\.[^/.]+$/, '')}.${item.format}`, item.blob);
});

zip.generateAsync({ type: "blob" }).then(function(blob) {
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = "processed_images.zip";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
}

// --- 初始化 ---
renderFileList(); // 初始加载时可能需要显示已有的文件(如果从localStorage加载)
compressionValueSpan.textContent = compressionLevelInput.value; // 初始化压缩值显示
});

// 注意: 为了实现"全部下载"功能,你需要引入 JSZip 库
// <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>


如何使用:

1. 保存文件:
* 将上面的 HTML 代码保存为 index.html
* 将上面的 CSS 代码保存为 style.css,并与 index.html 放在同一个文件夹下。
* 将上面的 JavaScript 代码保存为 script.js,并与 index.html 放在同一个文件夹下。
2. 引入 JSZip (可选,用于“全部下载”):
* 如果你想使用“全部下载”功能,在 index.html 的 <head> 部分或 </body> 结束标签之前,添加以下 <script> 标签:
html
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"&gt;&lt;/script&gt;

3. 打开 index.html 在浏览器中打开 index.html 文件。

界面亮点与兼容性:

* 视觉设计:
* 色彩: 采用柔和的绿色和青色作为主色调,配合白色和浅灰色背景,营造出清新、专业、友好的感觉。
* 排版: 使用现代的无衬线字体,保持清晰易读。
* 图标: 使用 Font Awesome 图标,增强视觉吸引力和功能提示。
* 卡片式设计: 将各个功能模块包装在卡片中,结构清晰,视觉层次分明。
* 阴影和过渡: 适当的阴影和 CSS 过渡效果,增加页面的立体感和动感,提升用户体验。
* 响应式设计:
* @media 查询用于调整不同屏幕尺寸下的布局。
* 在大屏幕上,采用多列布局,充分利用空间。
* 在中等屏幕(如平板)上,布局会进行调整,使内容仍然易于浏览。
* 在小屏幕(如手机)上,会切换到单列布局,元素堆叠显示,避免横向滚动,确保所有内容都能正常显示和操作。
* max-widthwidth: 100% 的使用,确保元素不会溢出容器。
* 交互性:
* 拖拽上传: 提供直观的拖拽区域,方便用户上传文件。
* 文件列表: 清晰显示已选择的文件,并提供删除功能。
* 选项清晰: 压缩质量滑块、格式选择下拉框、尺寸输入框等都容易理解和操作。
* 进度反馈: 在处理过程中,会有“正在处理中”的提示。
* 预览和下载: 处理后提供预览,并可以单独或批量下载。
* 兼容性:
* 现代浏览器: 基于 HTML5、CSS3 和现代 JavaScript API,兼容主流的现代浏览器(Chrome, Firefox, Safari, Edge)。
* 移动端: 通过响应式设计,在手机浏览器上也能提供良好的使用体验,所有操作按钮和输入框都足够大,便于触摸。

进一步的改进和考虑:

* 图片处理的效率: 对于大量或大型图片,前端处理可能会比较慢。可以考虑使用 Web Workers 来将图片处理移到后台线程,避免阻塞 UI。
* 错误处理: 增加更详细的错误提示,例如文件过大、不支持的图片格式等。
* 加载状态: 在图片处理过程中,可以显示更精细的进度条。
* 本地存储: 可以考虑使用 localStorage 来保存用户最近使用的选项,提高用户体验。
* 图片库: 如果需要处理很多图片,可以考虑使用更专业的图片处理库,如 Pintura, Cropper.js (虽然主要用于裁剪,但可集成)。
* 用户友好的文件命名: 考虑为下载的文件提供一个更友好的默认命名规则。
* 支持更多格式: 根据需求,可以扩展支持的输入和输出格式。

这个设计提供了一个坚实的基础,你可以根据具体需求进行扩展和优化。

#回复 AI问答 上传/拍照 我的