【好用推荐】免费在线图片压缩工具,附源码

73 阅读10分钟

大家好,我是码农刚子。前几天填写备案资料时需要上传营业执照,要求2MB以内,老板发给我的文件有十几MB,无法上传,用网上的在线工具,又担心安全性。以前也经常遇到需要图片太大的问题,基本上都是找别人用vip办公软件处理的,每次都要麻烦别人,于是我就想着自己做一个,使用方便还安全。接下来我给大家介绍一下我的图片压缩工具,源码在结尾。

免费在线图片压缩工具

使用说明

  • 上传图片后,通过滑块调整压缩质量(0%-100%)
  • 点击"上传并压缩图片"按钮进行处理
  • 压缩完成后,右侧会显示压缩后的图片
  • 点击"下载压缩图片"按钮保存结果

先体验一下吧!👉压缩图片

支持格式

  • JPEG (.jpg, .jpeg)
  • PNG (.png)
  • GIF (.gif)
  • WebP (.webp)
  • BMP (.bmp)

自定义压缩质量

  • 使用滑块自由调整压缩质量(0%-100%)
  • 0% - 最高压缩(最小文件尺寸,最低质量)
  • 100% - 最低压缩(最大文件尺寸,最高质量)
  • 默认值设置为30% - 良好平衡点
  • 实时显示压缩质量百分比

技术实现

  • 前端使用Fetch API发送multipart/form-data请求
  • 后端使用ASP.NET Core处理文件上传
  • 使用ImageService进行图片压缩处理
  • 响应状态码:200(成功)、400(错误请求)

源码如下

话不多说,直接开干!

<div class="container"> <header> <h1><i class="fas fa-file-image"></i> 免费在线图片压缩工具</h1> <p>保持画质清晰,快速缩小JPG/PNG/GIF/WebP文件,自定义压缩大小,压缩后可直接下载</p> </header> <div class="content"> <div class="upload-section"> <h2 class="section-title"><i class="fas fa-cloud-upload-alt"></i> 上传图片</h2> <a href="/" class="browse-btn refresh" target="_blank" title="码农观测站">首页</a> <button class="browse-btn refresh" onclick="window.location.reload();">刷新</button> <div class="upload-area" id="uploadArea"> <i class="fas fa-images"></i> <h3>拖放图片到此处</h3> <p>支持 JPG, PNG, GIF, WEBP 格式</p> <button class="browse-btn">选择图片</button> <input type="file" id="fileInput" class="file-input" accept="image/*"> </div> <div class="preview-container"> <div class="preview-title"><i class="fas fa-eye"></i> 图片预览</div> <div class="image-preview" id="imagePreview"> <img id="previewImage" src="" alt="预览图"> </div> <div class="compression-control"> <div class="quality-label"> <span>压缩质量:</span> <span class="quality-value" id="qualityValue">30%</span> </div> <div class="slider-container"> <input type="range" min="0" max="100" value="30" class="quality-slider" id="qualitySlider"> </div> <div class="slider-ticks"> <span>0%</span> <span>25%</span> <span>50%</span> <span>75%</span> <span>100%</span> </div> </div> <div class="progress-container" id="progressContainer"> <div class="progress-bar" id="progressBar"></div> </div> <button class="upload-btn" id="uploadBtn" disabled="">上传并压缩图片</button> <div class="api-info"> </div> </div> </div> <div class="result-section"> <h2 class="section-title"><i class="fas fa-download"></i> 压缩结果</h2> <div class="result-container"> <div class="result-content"> <div class="result-placeholder" id="resultPlaceholder"> <i class="fas fa-cloud-download-alt"></i> <p>图片压缩后将显示在这里</p> <p>您可以直接下载压缩后的图片</p> </div> <img id="compressedImage" class="compressed-image" src="" alt="压缩后的图片"> <a id="downloadLink" class="download-btn"> <i class="fas fa-download"></i> 下载压缩图片 </a> </div> <div class="response-area"> <h3 class="response-title"><i class="fas fa-comment-alt"></i> 处理状态</h3> <div class="response-content" id="responseContent"> 等待上传图片... </div> </div> </div> <div class="info-card"> <h4><i class="fas fa-info-circle"></i> 使用说明</h4> <ul> <li>上传图片后,通过滑块调整压缩质量(0%-100%)</li> <li>点击"上传并压缩图片"按钮进行处理</li> <li>压缩完成后,右侧会显示压缩后的图片</li> <li>点击"下载压缩图片"按钮保存结果</li> </ul> </div> </div> </div> <footer> <p>免费在线图片压缩工具 © 2025 | <a href="https://www.codeobservatory.cn" target="_blank" title="码农观测站">码农观测站</a></p> </footer> </div>
* { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 20px; } .container { width: 100%; max-width: 1200px; background-color: rgba(255, 255, 255, 0.97); border-radius: 20px; box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3); overflow: hidden; display: flex; flex-direction: column; } header { background: linear-gradient(to right, #1a2980, #26d0ce); color: white; padding: 30px 40px; text-align: center; position: relative; overflow: hidden; } header::before { content: ""; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: radial-gradient(circle, rgba(255,255,255,0.15) 0%, transparent 70%); transform: rotate(30deg); } header h1 { font-size: 2.5rem; margin-bottom: 10px; display: flex; align-items: center; justify-content: center; gap: 15px; position: relative; text-shadow: 0 2px 4px rgba(0,0,0,0.2); } header p { font-size: 1.2rem; opacity: 0.9; max-width: 700px; margin: 15px auto 0; position: relative; } .content { display: flex; padding: 0; flex-wrap: wrap; } .upload-section { flex: 1; min-width: 350px; padding: 40px; border-right: 1px solid #eee; position: relative; } .result-section { flex: 1; min-width: 350px; padding: 40px; background-color: #f9f9ff; display: flex; flex-direction: column; } .section-title { font-size: 1.6rem; color: #333; margin-bottom: 25px; display: flex; align-items: center; gap: 10px; position: relative; padding-bottom: 10px; } .section-title::after { content: ""; position: absolute; bottom: 0; left: 0; width: 50px; height: 3px; background: linear-gradient(to right, #1a2980, #26d0ce); border-radius: 3px; } .section-title i { color: #1a2980; } .upload-area { border: 3px dashed #1a2980; border-radius: 15px; padding: 40px 20px; text-align: center; cursor: pointer; transition: all 0.3s; background-color: #f0f4ff; margin-bottom: 25px; position: relative; overflow: hidden; } .upload-area:hover, .upload-area.dragover { background-color: #e6ebff; transform: translateY(-5px); box-shadow: 0 10px 25px rgba(26, 41, 128, 0.2); } .upload-area i { font-size: 4.5rem; color: #1a2980; margin-bottom: 20px; opacity: 0.8; } .upload-area h3 { font-size: 1.5rem; color: #444; margin-bottom: 15px; } .upload-area p { color: #666; margin-bottom: 20px; font-size: 1.05rem; } .browse-btn { background: linear-gradient(to right, #1a2980 0%, #26d0ce 100%); color: white; border: none; padding: 13px 35px; font-size: 1.1rem; border-radius: 50px; cursor: pointer; transition: all 0.3s; font-weight: 600; box-shadow: 0 5px 15px rgba(26, 41, 128, 0.3); position: relative; overflow: hidden; } .browse-btn:hover { transform: translateY(-3px); box-shadow: 0 8px 20px rgba(26, 41, 128, 0.4); } .browse-btn:active { transform: translateY(1px); } .browse-btn.refresh { position: absolute; top: 40px; right: 40px; padding: 7px 25px; } .file-input { display: none; } .preview-container { margin-top: 30px; text-align: center; } .preview-title { font-size: 1.3rem; margin-bottom: 20px; color: #555; display: flex; align-items: center; justify-content: center; gap: 10px; } .image-preview { width: 100%; max-height: 220px; border-radius: 12px; overflow: hidden; box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12); display: none; margin: 0 auto 25px; border: 1px solid #eee; } .image-preview img { width: 100%; height: 100%; object-fit: contain; background: #f8f8f8; } .compression-control { background: white; border-radius: 12px; padding: 20px; margin-bottom: 25px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08); } .quality-label { display: flex; justify-content: space-between; margin-bottom: 15px; font-size: 1.1rem; color: #444; } .quality-value { font-weight: 700; color: #1a2980; font-size: 1.2rem; min-width: 45px; text-align: right; } .slider-container { position: relative; height: 40px; } .quality-slider { width: 100%; height: 10px; -webkit-appearance: none; background: linear-gradient(to right, #ff416c, #ff4b2b, #ff9500, #ffcc00, #a8e063, #56ab2f); outline: none; border-radius: 5px; } .quality-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 25px; height: 25px; border-radius: 50%; background: #1a2980; cursor: pointer; box-shadow: 0 2px 10px rgba(0,0,0,0.2); border: 3px solid white; } .quality-slider::-moz-range-thumb { width: 25px; height: 25px; border-radius: 50%; background: #1a2980; cursor: pointer; box-shadow: 0 2px 10px rgba(0,0,0,0.2); border: 3px solid white; } .slider-ticks { display: flex; justify-content: space-between; padding: 0 12px; font-size: 0.85rem; color: #777; margin-top: 5px; } .upload-btn { width: 100%; padding: 16px; background: linear-gradient(to right, #00c853 0%, #64dd17 100%); color: white; border: none; border-radius: 12px; font-size: 1.2rem; font-weight: 600; cursor: pointer; transition: all 0.3s; box-shadow: 0 6px 18px rgba(0, 200, 83, 0.3); display: block; position: relative; overflow: hidden; } .upload-btn:hover { transform: translateY(-3px); box-shadow: 0 9px 22px rgba(0, 200, 83, 0.4); } .upload-btn:disabled { background: #cccccc; cursor: not-allowed; transform: none; box-shadow: none; } .progress-container { height: 10px; background-color: #e0e0e0; border-radius: 5px; margin: 20px 0; overflow: hidden; display: none; } .progress-bar { height: 100%; background: linear-gradient(to right, #1a2980 0%, #26d0ce 100%); width: 0%; transition: width 0.4s ease; } .comparison-container { display: flex; justify-content: space-around; margin: 25px 0; gap: 20px; } .comparison-item { text-align: center; flex: 1; background: white; padding: 20px 15px; border-radius: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); } .comparison-item h4 { margin-bottom: 12px; color: #555; font-size: 1.15rem; } .size-info { font-weight: 700; font-size: 1.3rem; color: #1a2980; } .api-info { background: #e3f2fd; padding: 15px; border-radius: 10px; margin-top: 20px; font-family: monospace; font-size: 0.95rem; color: #1a2980; } footer { text-align: center; padding: 25px; color: #666; background-color: #f5f5f5; border-top: 1px solid #eee; font-size: 1.05rem; } .result-container { background: white; border-radius: 15px; padding: 25px; box-shadow: 0 7px 20px rgba(0, 0, 0, 0.07); min-height: 180px; border: 1px solid #f0f0f0; flex-grow: 1; display: flex; flex-direction: column; } .result-content { flex-grow: 1; display: flex; flex-direction: column; justify-content: center; align-items: center; } .compressed-image { max-width: 100%; max-height: 250px; border-radius: 12px; box-shadow: 0 5px 15px rgba(0,0,0,0.1); margin-bottom: 25px; border: 1px solid #eee; display: none; } .download-btn { display: inline-block; background: linear-gradient(to right, #1a2980 0%, #26d0ce 100%); color: white; padding: 14px 30px; font-size: 1.1rem; font-weight: 600; border-radius: 50px; text-decoration: none; transition: all 0.3s; box-shadow: 0 5px 15px rgba(26, 41, 128, 0.3); display: none; align-items: center; gap: 10px; } .download-btn:hover { transform: translateY(-3px); box-shadow: 0 8px 20px rgba(26, 41, 128, 0.4); } .info-card { background: white; border-radius: 15px; padding: 25px; box-shadow: 0 7px 20px rgba(0, 0, 0, 0.07); margin-bottom: 30px; border: 1px solid #f0f0f0; } .info-card h4 { color: #1a2980; margin-bottom: 20px; font-size: 1.3rem; display: flex; align-items: center; gap: 12px; } .info-card ul { list-style-type: none; padding-left: 5px; } .info-card li { margin-bottom: 14px; padding-left: 32px; position: relative; font-size: 1.05rem; color: #555; line-height: 1.5; } .info-card li:before { content: "•"; color: #1a2980; font-size: 2rem; position: absolute; left: 0; top: -8px; } .response-area { background: white; border-radius: 15px; padding: 25px; box-shadow: 0 7px 20px rgba(0, 0, 0, 0.07); min-height: 100px; border: 1px solid #f0f0f0; margin-top: 20px; } .response-title { color: #1a2980; margin-bottom: 15px; font-size: 1.3rem; display: flex; align-items: center; gap: 12px; } .response-content { font-size: 1.1rem; line-height: 1.6; color: #555; min-height: 60px; display: flex; align-items: center; justify-content: center; padding: 15px; text-align: center; } @media (max-width: 768px) { body { padding:20px 0; } header { padding: 30px 20px; } .content { flex-direction: column; } .upload-section { border-right: none; border-bottom: 1px solid #eee; padding:20px; } .result-section { padding:20px; } header h1 { font-size: 2rem; } header p { font-size: 1rem; } .browse-btn.refresh { top:20px; right:20px; } a.browse-btn.refresh { right:130px; } } .success-message { color: #00c853; font-weight: 600; } .error-message { color: #f44336; font-weight: 600; } .result-placeholder { text-align: center; color: #777; font-size: 1.1rem; padding: 40px 20px; } .result-placeholder i { font-size: 4rem; color: #e0e0e0; margin-bottom: 20px; }
document.addEventListener('DOMContentLoaded', function () { const uploadArea = document.getElementById('uploadArea'); const fileInput = document.getElementById('fileInput'); const uploadBtn = document.getElementById('uploadBtn'); const imagePreview = document.getElementById('imagePreview'); const previewImage = document.getElementById('previewImage'); const responseContent = document.getElementById('responseContent'); const progressContainer = document.getElementById('progressContainer'); const progressBar = document.getElementById('progressBar'); const originalSize = document.getElementById('originalSize'); const compressedSize = document.getElementById('compressedSize'); const qualitySlider = document.getElementById('qualitySlider'); const qualityValue = document.getElementById('qualityValue'); const compressedImage = document.getElementById('compressedImage'); const downloadLink = document.getElementById('downloadLink'); const resultPlaceholder = document.getElementById('resultPlaceholder'); // 压缩质量滑块事件 qualitySlider.addEventListener('input', function () { qualityValue.textContent = this.value + '%'; }); // 点击上传区域触发文件选择 uploadArea.addEventListener('click', () => { fileInput.click(); }); // 拖放功能 ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { uploadArea.addEventListener(eventName, preventDefaults, false); }); function preventDefaults(e) { e.preventDefault(); e.stopPropagation(); } ['dragenter', 'dragover'].forEach(eventName => { uploadArea.addEventListener(eventName, highlight, false); }); ['dragleave', 'drop'].forEach(eventName => { uploadArea.addEventListener(eventName, unhighlight, false); }); function highlight() { uploadArea.classList.add('dragover'); } function unhighlight() { uploadArea.classList.remove('dragover'); } // 处理文件放置 uploadArea.addEventListener('drop', handleDrop, false); function handleDrop(e) { const dt = e.dataTransfer; const files = dt.files; if (files.length) { handleFiles(files); } } // 处理文件选择 fileInput.addEventListener('change', function () { if (this.files.length) { handleFiles(this.files); } }); // 处理选中的文件 function handleFiles(files) { const file = files[0]; if (!file.type.match('image.*')) { responseContent.innerHTML = '<span class="error-message">错误:请选择图片文件(JPG, PNG, GIF, WEBP)</span>'; return; } // 重置结果区域 compressedImage.style.display = 'none'; downloadLink.style.display = 'none'; resultPlaceholder.style.display = 'block'; // 显示预览 const reader = new FileReader(); reader.onload = function (e) { previewImage.src = e.target.result; imagePreview.style.display = 'block'; uploadBtn.style.display = 'block'; uploadBtn.disabled = false; }; reader.readAsDataURL(file); // 更新响应内容 responseContent.innerHTML = '<span class="success-message">图片已选择,点击"上传并压缩图片"按钮开始处理...</span>'; } // 上传按钮点击事件 uploadBtn.addEventListener('click', function () { if (!fileInput.files.length) return; const file = fileInput.files[0]; const quality = parseInt(qualitySlider.value); const formData = new FormData(); formData.append('imageFile', file); formData.append('compressionQuality', quality); // 显示进度条 progressContainer.style.display = 'block'; progressBar.style.width = '0%'; // 禁用上传按钮 uploadBtn.disabled = true; uploadBtn.textContent = '处理中...'; uploadBtn.style.background = 'linear-gradient(to right, #ff9800 0%, #ff5722 100%)'; // 更新响应内容 responseContent.innerHTML = '<span class="success-message">正在上传并压缩图片,请稍候...</span>'; // 模拟进度更新 const progressInterval = setInterval(() => { const currentWidth = parseInt(progressBar.style.width) || 0; if (currentWidth < 90) { progressBar.style.width = (currentWidth + 10) + '%'; } }, 300); // 发送请求到API fetch('/api/yourapiname', { method: 'POST', body: formData }) .then(response => { debugger clearInterval(progressInterval); progressBar.style.width = '100%'; if (response.ok) { return response.blob(); } else if (response.status === 400) { return response.text().then(text => { throw new Error(text || '无效请求'); }); } else { throw new Error(`请求失败,状态码: ${response.status}`); } }) .then(blob => { // 创建压缩图片的URL const compressedUrl = URL.createObjectURL(blob); // 显示压缩后的图片 compressedImage.src = compressedUrl; compressedImage.style.display = 'block'; // 设置下载链接 downloadLink.href = compressedUrl; downloadLink.download = `compressed_${fileInput.files[0].name}`; downloadLink.style.display = 'inline-block'; // 隐藏占位符 resultPlaceholder.style.display = 'none'; // 更新UI setTimeout(() => { responseContent.innerHTML = '<span class="success-message">图片压缩成功!可下载压缩后的图片</span>'; uploadBtn.textContent = '上传成功!'; uploadBtn.style.background = 'linear-gradient(to right, #00c853 0%, #64dd17 100%)'; }, 500); }) .catch(error => { clearInterval(progressInterval); progressBar.style.backgroundColor = '#f44336'; responseContent.innerHTML = `<span class="error-message">错误: ${error.message}</span>`; uploadBtn.textContent = '上传失败,重试'; uploadBtn.disabled = false; uploadBtn.style.background = 'linear-gradient(to right, #f44336 0%, #e91e63 100%)'; }); }); });

版权声明:本文为作者原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
作者: 码农刚子
原文链接: www.codeobservatory.cn/archives/fb…