Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rendering image from API response in NextJS - just downloads base64 file

I am working on a new project and learning ReactJS. I have saved an image in base64 to a MySQL database and I am now trying to do a GET request so the image is shown in the browser instead of it being downloaded, however, although it attempts to download the file, the file is just a file containing the base64 string instead of an actual image.

The file in the database looks like the below (only a snippet of the base64)

data:image/png;base64,iVBORw0KGgoAAAA

The API to fetch the image is as below:

export default async function handler(req : NextApiRequest, res : NextApiResponse) {
    const prisma = new PrismaClient()

    if (req.method === "GET")
    {
        const {image_id} = req.query;
        const image = await prisma.images.findFirst({
            where: {
                imageId: parseInt(image_id)
            }
        });
        const decoded = Buffer.from(image.content).toString("base64");
        console.log(decoded)
        res.status(200).send(decoded);
    }
    else
    {
        res.status(405).json(returnAPIErrorObject(405, "Method not supported by API endpoint"));
    }
}

I've modified the next.config.js to provide a custom header response which contains the below:

module.exports = {
    async headers() {
        return [
            {
                source: '/api/images/:image_id',
                headers: [
                    {
                        key: 'Content-Type',
                        value: 'image/png:Base64'
                    }
                ]
            }
        ]
    }
}

As mentioned, when I go to the URL http://localhost:3000/api/images/4 (4 being the image id) it downloads a file that contains the base64 string that is in the database, instead of showing the image in the browser.

UPDATE

Based on the link in the comment from @sean w it now attempts to display the image but instead of showing the actual picture, it just shows a blank window with a white square as shown in the screenshot below.

My code now looks like the following:

        const {image_id} = req.query;
        const image = await prisma.images.findFirst({
            where: {
                imageId: parseInt(image_id)
            }
        });

        const decoded = Buffer.from(image.content, 'base64').toString();

        let imageContent = decoded.replace(/^data:image\/png;base64,/, '');

        console.log(decoded);

        res.writeHead(200, {
            'Content-Type': 'image/png',
            'Content-Length': imageContent.length
        });
        res.end(imageContent);

Below is a screenshot showing what actually gets rendered on the page instead of my actual image.

How images is being shown instead of actual image

like image 547
Boardy Avatar asked Oct 20 '25 00:10

Boardy


1 Answers

I've figured out the issue, instead of creating the buffer from the database which I think looks like Prisma as the column was a blob was giving me a buffer anyway. , I first extract the base64 string from the DB and remove the data:image/png;base64 from the string and then create a buffer from that string and send that for the response:

const {image_id} = req.query;
        const image = await prisma.images.findFirst({
            where: {
                imageId: parseInt(image_id)
            }
        });

        const decoded = image.content.toString().replace("data:image/png;base64,", "");
        const imageResp = new Buffer(decoded, "base64");

        res.writeHead(200, {
            'Content-Type': 'image/png',
            'Content-Length': imageResp.length
        });
        res.end(imageResp);
like image 135
Boardy Avatar answered Oct 23 '25 00:10

Boardy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!