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

大家好,我是码农刚子。前几天填写备案资料时需要上传营业执照,要求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 版权协议,转载请附上原文出处链接和本声明。
作者: 码农刚子
原文链接: https://www.codeobservatory.cn/archives/fb2da740.html

发表评论

评论已关闭。

相关文章