Image Compression

by sbhomra

HTML

<div style="font-family: sans-serif; padding: 20px;">
  <h3>Upload Image</h3>
  <input type="file" id="image-selector" accept="image/*" />
  <div id="status" style="margin-top: 10px; font-weight: bold;"></div>

  <div style="display: flex; gap: 20px; margin-top: 20px; flex-wrap: wrap;">
    <div style="flex: 1; min-width: 300px;">
      <h3>Original Image</h3>
      <p id="original-meta"></p>
      <br />
      <img
        id="original-preview"
        style="max-width: 100%; border: 1px solid #ddd; display: none;"
      />
    </div>

    <div style="flex: 1; min-width: 300px;">
      <h3>Compressed Image</h3>
      <p id="compressed-meta"></p>
      <img
        id="compressed-preview"
        style="max-width: 100%; border: 1px solid #ddd; display: none;"
      />
    </div>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/browser-image-compression.js"></script>

JavaScript

const imageSelectorElem = document.getElementById('image-selector');
const compressionStatusElem = document.getElementById('status');

imageSelectorElem.addEventListener('change', async (event) => {
  const file = event.target.files[0];
  if (!file) return;

  compressionStatusElem.innerText = 'Processing...';

  // 1. Display Original.
  const originalPreview = document.getElementById('original-preview');
  originalPreview.src = URL.createObjectURL(file);
  originalPreview.style.display = 'block';
  document.getElementById('original-meta').innerText =
    `Size: ${(file.size / 1024 / 1024).toFixed(2)} MB`;

  // 2. Compression Options (Capped at 1MB).
  const options = {
    maxSizeMB: 1,
    maxWidthOrHeight: 1920,
    useWebWorker: true,
  };

  try {
    // 3. Perform Compression.
    const compressedBlob = await imageCompression(file, options);

    // 4. Display Compressed Result.
    const compressedPreview = document.getElementById('compressed-preview');
    compressedPreview.src = URL.createObjectURL(compressedBlob);
    compressedPreview.style.display = 'block';

    const savings = (
      ((file.size - compressedBlob.size) / file.size) *
      100
    ).toFixed(1);
    document.getElementById('compressed-meta').innerHTML =
      `Size: ${(compressedBlob.size / 1024 / 1024).toFixed(2)} MB <br> 
       <span style="color: green;">Saved ${savings}% of data</span>`;

    compressionStatusElem.innerText = 'Compression complete.';
  } catch (error) {
    compressionStatusElem.innerText = 'Error: ' + error.message;
  }
});