Calculate file size of a dataURL (cost)

Asked

Viewed 487 times

2

I’m uploading an image to Base64 (dataURL) for an application that uses express. As the user is doing the "cropping" of this image on the front end I found no other way to send but by dataURL... the application has a general limit of 2mb per upload plus, the validation of the limit of this image would be 250kb.

Researching found numerous ways to make this validation among which I am (per hour) applying the following strategy:

  • apply a RegExp to check if the string is a dataURL
  • retrieve the part of the encoded string in Base64 using split()
  • decode the Base64 to extract the length of the raw data

// função para decodificar o base64
function atob(str) {
    return new Buffer(str, 'base64').toString('binary')
}
// a string (dataURL)
let avatar = req.body.avatar
// regex
let BASE64_REGEX = /^(data:\w+\/[a-zA-Z\+\-\.]+;base64)$/gi
// dividir
let arr = avatar.split(','),
    mime = arr[0].match(/:(.*?);/)[1], // obter o mime-type
    isBase64 = BASE64_REGEX.test(arr[0]) // testar
// decodificar e obter o comprimento dos dados brutos
console.log( 'size is: ' + atob(arr[1]).length )

Researching a little more to know if I could "do better" found this article which reports that it is not necessary to "do all this juggling" and these two topics in the ONLY (topic A, topic B) that show the formula to reach the file length.

I decided to put this formula into practice as follows:

// a string (dataURL) (simplificado sem verificação)
let avatar = req.body.avatar.split(',')[1]
// armazenar como referência os dois últimos caracteres da string (para checar o padding)
let pad = avatar.slice(-2)
// definir o número de bytes para extrair (baseado no padding)
let padlen = (pad === '==') ? 2 : ((pad.slice(-1) === '=') ? 1 : null)
// calcular segundo a fórmula
console.log( 'size is: ' + ((avatar.length / 4) * 3 - padlen) )

As expected in both ways the result is the same:

size is: 72055

Link to the test on rextester.with


The question itself: is not how to calculate but rather the cost of this calculation

As this is a "model" that can be used in other parts of the application and as I have no experience in optimization use the approach with Buffer would or would not be "more expensive" (would consume more resources) than using slice() and perform the mathematical operation?

I appreciate any help... and knowing the rules of the community, I’m not looking for answers based on opinion. A qualified response with sources or test template (or reference to one) would be welcome. Grateful.

  • I recommend testing both forms on https://jsperf.com to check performance, the site is quite complete. I don’t have access to it here where I am now, otherwise I would run the tests.

  • Um... if I’m not mistaken this site does not run Nodejs (only the javascript front-end) and so neither will recognize the Buffer but I appreciate your comment

  • Right... however, given that the user will manipulate the image via front-end, this calculation of the size of the Base64 string could be done in front-end as well, which would make the cost for the server equal to zero. but there depends a little also of the target audience and the security that you want with your application. However, it would not have been possible to obtain a certain value from length of Base64 without calculations beyond such length would it be certain that the file exceeded the stipulated limit? This would avoid calculations.

  • Although the server has a limit of 2mb per form, it is not reliable to rely on front-end validation. Moreover I use an external service to store files so check the size of the images is essential

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.