Donaldcwl / browser-image-compression

Image compression in web browser
MIT License
1.3k stars 160 forks source link

Crop Functionality #87

Open metacrawler23 opened 4 years ago

metacrawler23 commented 4 years ago

Is there a way we can have an auto crop functionality based on a specific aspect ratio or fixed width in pixel

sayhicoelho commented 1 year ago

It would be nice to have crop feature here, but for anyone else having this issue, I just made a crop function:

import imageCompression from 'browser-image-compression'

export async function resizeImage(file, size = 1280) {
  const compressedFile = await imageCompression(file, {
    maxWidthOrHeight: size,
    fileType: 'image/jpeg',
    initialQuality: 0.5,
    useWebWorker: true
  })

  return compressedFile
}

export async function cropImage(file, size = 150) {
  const bmp = await createImageBitmap(file)

  const { width, height } = bmp

  let newWidth = width
  let newHeight = height
  let newPosX = 0
  let newPosY = 0

  if (width > height) {
    newWidth = (width / height) * size
    newHeight = size
    newPosX = -(newWidth - size) / 2
  } else if (width < height) {
    newWidth = size
    newHeight = (height / width) * size
    newPosY = -(newHeight - size) / 2
  } else {
    newWidth = size
    newHeight = size
  }

  const canvas = document.createElement('canvas')
  // const canvas = new OffscreenCanvas(size, size) // Use this line if you plan to run this code on Web Workers.
  const ctx = canvas.getContext('2d')

  canvas.width = size
  canvas.height = size

  ctx.drawImage(bmp, newPosX, newPosY, newWidth, newHeight)

  bmp.close()

  return new Promise(resolve => canvas.toBlob(resolve, 'image/jpeg', 0.5))
}

Usage

try {
  const file = e.target.files[0]
  const resizedImage = await resizeImage(file, 1280)
  const croppedImage = await cropImage(resizedImage, 150)
} catch (err) {
  console.error(err)
}