denooak

Display base64 image with Deno's Oak package


I've got a base64 encoded image stored in my database, so the start looks like this data:image/png;base64,iVB.. and I return it from the database at my 'image' endpoint.

I could of course just fetch the content using JavaScript and include the base64 string as img source and it would render just fine, but I also want to be able to view the image when I go to the endpoint with my browser. I've tried a combination of different headers but couldn't get it too work.

How do I render a base64 image using Oak?

EDIT:

This is the code I ended up using, for anyone interested!

const getImage = async (
  { params, response }: { params: { id: string }; response: Response },
) => {
  // Get the image using the ID from the URL
  const image = await imageDatabase.findOne({ _id: ObjectId(params.id) });

  // If there is no image found
  if (!image) {
    response.status = 404;
    return;
  }

  // Return the image to the user
  const semicolonIndex = image.base64!.indexOf(';')
  const colonIndex = image.base64!.indexOf(':')
  const commaIndex = image.base64!.indexOf(',')

  const imageSize = image.base64!.slice(colonIndex + 1, semicolonIndex);
  const imageData = image.base64!.slice(commaIndex + 1);

  response.headers.set('Content-Type', imageSize)
  response.body = base64.toUint8Array(imageData)
};

Solution

  • HTTP doesn't support base64 image content. You should decode it and return with content type.

    const images: any = {
      beam: 'data:image/png;base64,<base64-string>',
      google: 'data:image/png;base64,<base64-string>',
    }
    
    router.get('/image/:id', ctx => {
      if (ctx.params && ctx.params.id && ctx.params.id in images) {
        const image: string = images[ctx.params.id]
        const colonIdx = image.indexOf(':')
        const semicolonIdx = image.indexOf(';')
        const commaIdx = image.indexOf(',')
        // extract image content type
        ctx.response.headers.set('Content-Type', image.slice(colonIdx + 1, semicolonIdx))
        // encode base64
        ctx.response.body = base64.toUint8Array(image.slice(commaIdx + 1))
      }
    })
    

    To find full code, see code on github

    Or you can run my sample directly

    deno run -A https://raw.githubusercontent.com/XDean/StackOverflow/master/src/main/deno/Q66697683.ts