图片格式转换器 - PNG, JPG, WebP, AVIF在线转换
在浏览器中转换PNG、JPG、WebP和AVIF格式的图片。批量转换、质量控制和文件大小对比 — 无需上传到服务器。
常见问题
什么是图片格式转换器,为什么需要它?
图片格式转换器可以将图片从一种文件格式转换为另一种格式(例如PNG转WebP、JPG转AVIF)。这对于Web开发至关重要,因为WebP和AVIF等现代格式比传统的PNG和JPEG提供更小的文件大小,从而带来更快的页面加载速度、更低的带宽成本和更好的Core Web Vitals分数。一张典型的2MB PNG图片可以在最小视觉质量损失的情况下转换为不到500KB的WebP。
如何使用这个图片格式转换器?
1. 将图片拖放到上传区域(或点击浏览文件)。2. 选择目标输出格式(PNG、JPG、WebP或AVIF)。3. 调整有损格式的质量滑块(默认为80%)。4. 点击单个图片的「转换」或「全部转换」进行批量处理。5. 查看转换前后的文件大小对比。6. 下载单个图片或使用「全部下载」获取ZIP压缩包。
我的图片数据安全吗?图片会上传到服务器吗?
您的图片100%安全,永远不会离开您的浏览器。所有格式转换均使用HTML5 Canvas API在客户端执行。没有任何图片数据会传输到任何服务器,使这个工具完全私密。页面加载后,您甚至可以离线使用它。
PNG、JPG、WebP和AVIF有什么区别?
PNG是支持透明度的无损格式,最适合图形和图标,但文件较大。JPG/JPEG是不支持透明度的有损格式,最适合照片,具有良好的压缩率。WebP是一种现代格式,支持有损和无损压缩以及透明度,通常比JPEG小25-35%,拥有95%以上的浏览器支持。AVIF是最新的格式,具有最佳压缩比(比WebP小20-50%),支持透明度,但浏览器支持仍在增长中。
为什么转换后的文件比原始文件更大?
当从高度压缩的格式转换为效率较低的格式时(例如WebP转PNG),或者当原始文件已经很好地优化时,可能会出现这种情况。Canvas API的PNG输出始终是无损的,可能比有损替代方案更大。尝试使用WebP或AVIF并将质量设置为80%,以获得最佳的大小与质量比。
这个工具在所有浏览器中都支持AVIF吗?
通过Canvas API的AVIF编码目前在Chrome 96+和Edge 96+中受支持。Firefox和Safari的AVIF编码支持有限。该工具会自动检测您的浏览器功能,如果不支持AVIF,将禁用该选项并显示明确的提示信息。
转换为JPG时透明度会怎样?
JPEG不支持透明度。将透明的PNG或WebP图片转换为JPG时,透明区域将用背景色填充(默认为白色)。当选择JPG作为输出格式时,工具会显示颜色选择器,您可以使用它选择自定义背景色。
可以一次转换多张图片吗?
是的,批量转换同时支持最多20张图片。所有图片将使用相同的目标格式和相同的质量设置进行转换。转换后,使用「全部下载(ZIP)」将所有转换后的图片下载为一个ZIP文件。
代码示例
// Client-side image format conversion using Canvas API
async function convertImageFormat(file, outputFormat, quality = 0.8) {
return new Promise((resolve, reject) => {
const img = new Image();
const url = URL.createObjectURL(file);
img.onload = () => {
URL.revokeObjectURL(url);
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
// Fill background for JPEG (no transparency support)
if (outputFormat === 'image/jpeg') {
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
ctx.drawImage(img, 0, 0);
canvas.toBlob(
(blob) => {
if (!blob) {
reject(new Error('Conversion failed'));
return;
}
resolve({
blob,
originalSize: file.size,
convertedSize: blob.size,
inputFormat: file.type,
outputFormat: outputFormat,
sizeDiff: Math.round(((blob.size - file.size) / file.size) * 100),
});
},
outputFormat,
outputFormat === 'image/png' ? undefined : quality
);
};
img.onerror = () => {
URL.revokeObjectURL(url);
reject(new Error('Failed to load image'));
};
img.src = url;
});
}
// Check AVIF support
async function checkAvifSupport() {
const canvas = document.createElement('canvas');
canvas.width = 1;
canvas.height = 1;
return new Promise((resolve) => {
canvas.toBlob(
(blob) => resolve(blob?.type === 'image/avif'),
'image/avif',
0.5
);
});
}
// Batch conversion
async function convertBatch(files, outputFormat, quality = 0.8) {
const results = [];
for (const file of files) {
try {
const result = await convertImageFormat(file, outputFormat, quality);
results.push({ filename: file.name, ...result });
} catch (error) {
results.push({ filename: file.name, error: error.message });
}
}
return results;
}
// Usage
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', async (e) => {
const files = Array.from(e.target.files);
const results = await convertBatch(files, 'image/webp', 0.8);
results.forEach((result) => {
if (result.error) {
console.error(`${result.filename}: ${result.error}`);
} else {
console.log(
`${result.filename}: ${result.inputFormat} -> ${result.outputFormat}, ` +
`${result.originalSize} -> ${result.convertedSize} (${result.sizeDiff}%)`
);
}
});
});