0

For SEO optimizaion I'm attemting to low off the size of the files that the user attempts to send (I know I could have some size limitation or something not doing so because of the UX). and I'm doing it in the front-end cause I want to use pre-signed URL method (AWS S3)

process(event: any, imageInputElement: any, maxWidth: number): any {
  return new Promise<any>((resolve, reject) => {
    try {
      const file = event.target.files[0]
      console.log(' ~ file: index.vue ~ line 143 ~ process ~ file', file)
      const fileSize = file.size
      if (fileSize < 100000) return
      if (!file) return
      const reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = function (event: any) {
        const src = event.target.result
        const canvas = document.createElement('canvas') as any
        const imgElement = document.createElement('img') as any
        imgElement.src = src
        imageInputElement.src = event.target?.result
        console.log(maxWidth)
        imageInputElement.onload = function (e: any) {
          const scaleSize = maxWidth / e.target.width
          canvas.width = maxWidth
          canvas.height = e.target.height * scaleSize
          const ctx = canvas.getContext('2d')
          ctx.drawImage(e.target, 0, 0, canvas.width, canvas.height)
          const compressPer = (data: number) => {
            const result = 10000000 / data
            if (Math.trunc(result) >= 100) {
              return 100
            } else if (Math.trunc(result) < 1) {
              return 1
            } else {
              return Math.trunc(result)
            }
          }
          const srcEncoded = ctx.canvas.toDataURL(
            e.target,
            'image/jpeg',
            compressPer(fileSize)
          )
          const result = new File([srcEncoded], `${file.name}`, {
            type: 'image/jpeg',
          })
          console.log(
            ' ~ file: index.vue ~ line 186 ~ process ~ result',
            result
          )

          resolve(result)
        }
      }
    } catch (error: any) {
      reject(error)
    }
  })
},

This function gets called every time the user changes a file input.

event: is the default change event that includes the file itself. imageInputElement: is the element that I want to render the new file in it. and maxWidth is the width that I pass to the function to specify the max width

The actual problem: the file will become visible in the browser and gets uploaded to the s3 bucket but the file is crashed when I want to download it again.

  • The image resizing method worked without problem during my tests. Please show the code that uploads the images. Does it work correctly with small images that do not require resizing? – Yogi Jul 15 '22 at 07:49
  • yes the upload function works with a file that I didn't resize @Yogi – kouroshtajalliepour Jul 15 '22 at 08:56

1 Answers1

0

instead of

const file = event.target.files[0]

I should have used

var blobBin = atob(srcEncoded.split(',')[1]);
          var array = [];
          for(let i = 0; i < blobBin.length; i++) {
              array.push(blobBin.charCodeAt(i));
          }
          const result:any = new Blob([new Uint8Array(array)], {type: 'image/png'});

got my answer from here