I'm trying to get the Uint8Contents
as Blob to convert to base64 and store it as PgSQL bytea
coming from the ArrayBuffer
/Buffer
using multer
middleware for Expressjs.
Most of the answers refer to saving it in a file system first, but how would you use the multer memory storage? (I've used it this way)
import { Router, Request, Response } from 'express'
import multer from 'multer'
const storage = multer.memoryStorage()
const upload = multer({ storage: storage })
const api = Router()
api.post('/customer/:customer_id/photo', upload.single('photo'),
async (req: Request, res: Response) => {
const customerId = req.params.customer_id
const photoBuffer = req?.file?.buffer as Buffer
const arrayBuffer = photoBuffer.buffer.slice(
photoBuffer.byteOffset,
photoBuffer.byteOffset + photoBuffer.byteLength
)
const uInt8Contents = photoBuffer.readUInt8(photoBuffer.byteOffset)
console.log("uInt8Contents",uInt8Contents)
// const arrayBuffer = Uint8Array.from(photoBuffer).buffer
// const photoBlob = Buffer.from(arrayBuffer).Blob([arrayBuffer])
console.log("bufferPhoto", arrayBuffer)
// TODO: Need a code for converting array buffer or buffer to be the correct image Blob
const base64Photo = Buffer.from(arrayBuffer).toString('base64')
// Store base 64 photo in PgSQL bytea
// ...
}
)
I just couldn't figure out how to get the correct Blob to be converted as base64 and store it in PgSQL as bytea
.
So, the question is: On the second to the last line, how would I convert the file into a Blob
?
I get this output, but it does not seem to be the Uint8Contents
of the blob because the image does not display at all.
ArrayBuffer {
[Uint8Contents]: <ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 48 00 48 00 00 ff e2 02 a0 49 43 43 5f 50 52 4f 46 49 4c 45 00 01 01 00 00 02 90 6c 63 6d 73 04 30 00 00 6d 6e 74 72 52 47 42 20 58 59 5a 20 07 dd 00 0a 00 08 00 17 00 2b 00 36 61 63 73 70 41 50 50 4c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 2527 more bytes>,
byteLength: 2627
}
I found this issue: https://github.com/dherault/serverless-offline/issues/464
It was basically a serverless-offline
issue: When a server is running in serverless-offline
and the image is uploaded, the binary image gets distorted like this:
Where the binary image should look like this, instead:
In short, the characters are being changed by serverless-offline
. The link, however, suggests that if you are going to deploy the code in a non-serverless-offline
environment, it will work.
So, this code will still work when deployed:
import { Router, Request, Response } from 'express'
import multer from 'multer'
const storage = multer.memoryStorage()
const uploadPhoto = multer({ storage: storage }).single('upload')
const api = Router()
v1Api.post('/user/:user_id/photo', uploadPhoto, async (req: Request, res: Response) => {
const userId = req.params.user_id
const photoBuffer = req?.file?.buffer as Buffer
const binaryPhoto = Buffer.from(photoBuffer).toString('binary')
const base64Photo = Buffer.from(binaryPhoto).toString('base64')
console.log(base64photo) // Save this base64photo as bytea
})
Otherwise, configure the serverless.yml
to support binary using this plugin aws-serverless-express-binary
.
Edit
We deployed it in an environment and it seems to work correctly.