【好用推薦】免費在線圖片壓縮工具,附源碼
大家好,我是碼農剛子。前幾天填寫備案資料時需要上傳營業執照,要求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 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 版權協議,轉載請附上原文出處鏈接和本聲明。
作者: 碼農剛子
原文鏈接: https://www.codeobservatory.cn/archives/fb2da740.html

浙公網安備 33010602011771號