javascripthtml5-canvasblobimage-compressiontodataurl

HTML5 Canvas Compression's DataURL() outputing larger size than original


so I've implemented closely to this implementation: Use HTML5 to resize an image before upload.

I have the following compressedImgURL:

compressedImageURL = canvas.toDataURL('image/jpeg', 0.8)

In addition to compress it, I need to send the server not in base64, but rather in jpeg form.

I made this util function:

            const byteString = atob(compressedImageURL .split(',')[1])
            const mimeString = compressedImageURL .split(',')[0].split(':')[1].split(';')[0]
            const ab = new ArrayBuffer(byteString.length)
            const ia = new Uint8Array(ab)
            for (let i = 0; i < byteString.length; i++) {
                ia[i] = byteString.charCodeAt(i)
            }
            // construct the file object
            const bb = new Blob([ia], { type: mimeString })

I've checked images with 2MB file and compression seems to be doing it's job (I can see that when I console.log(bb.size) I see the size has been reduced).

However when I upload an image with 10MB, I see that it's been increased to 19MB.

From my understanding, base64 actually adds 30% of the original size, but I'd thought adding the compresion ratio (in this case 0.8) would prevent it.

Is there certain threshold that the dataURL has a limitation of compressing an image?


Solution

  • For canvas.toDataURL, the second argument is for image quality not a compression ratio. (See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL#Parameters)

    The actual compression ratio depends on the image itself, though some quick searching yielded this answer: https://stackoverflow.com/a/26782154/6184972. Also note that the 10MB picture that you're using is probably already compressed, and the compression ratio usually refers to the size of an uncompressed image.

    Since the relationship between compression and quality are unpredictable beforehand, one possible approach would be to decrease quality until the image is the desired size.