How to render base64 image on response

Hello, everyone.

I'm looking for a solution to render a base64 image string on my response. Is it possible?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="AM-set-image-response">
    <Set>
        <StatusCode>200</StatusCode>
        <ReasonPhrase>OK</ReasonPhrase>
        <Payload contentType="image/jpeg">{base64-image}</Payload>
    </Set>
    <AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>

The response appears broken

0 8 1,081
8 REPLIES 8

That probably won't work.

What is contained within base64-image? How ddid you set that variable?

It's a jpeg formatted in base64. I got it from an external source.

I assigned it on assigned message policy for a PoC to help frontend team.

Normally, for delivering images, you want to send the UN-encoded bytes for the image.

To do that, If you have a string that is the base64-encoding of the image bytes, then

  • decode the string to get a byte array
  • send THAT byte array as the message content.

You can't use AssignMessage (not today, anyway) to set a non-string into the message content.

To do that, you will need to use a Java callout. This one will do that. You may need to couple it with a base64-decoder callout. Like this one.

Probably encode the message content into Base64 format & assign.

How can I load the image in the browser instead of saving it in the file ?

I already have base64 value of an image. I want to generate an endpoint where I can pass this base64 value and it should return me an image in the browser itself.

Pravin,

This works for me.

<AssignMessage name='AM-Response'>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
  <Set>
    <Payload contentType='text/html'>
<html>
  <head>
    <title>Cute Kittens</title>
  </head>
  <body>
    <div>
      <img src="data&colon;image/png;base64, {image_data}" alt="Cute kittens" />
    </div>
  </body>
</html>
</Payload>
    <ReasonPhrase>OK</ReasonPhrase>
    <StatusCode>200</StatusCode>
  </Set>
  <AssignTo>response</AssignTo>
</AssignMessage>

 

Below is not working for me and I get below responseReponse.pngReponse.png

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage name="AM-Response">
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <Set>
        <Payload contentType="text/html">
            <html>
                <head>
                    <title>Cute Kittens</title>
                </head>
                <body>
                    <div>
                        <img src="data&colon;image/png;base64, {request.queryparam.base}" alt="Cute kittens"/>
                    </div>
                </body>
            </html>
        </Payload>
        <ReasonPhrase>OK</ReasonPhrase>
        <StatusCode>200</StatusCode>
    </Set>
    <AssignTo>response</AssignTo>
</AssignMessage>

 

It is likely that what you are seeing is due to encoding issues.

Base64 encoding will produce some characters as '+'. For example, when I base64-encode a small image I have on my machine, the first set of characters is

base64-encoding-produces-plus.png

I circled some of the + characters in the above.

When I try to pass that directly as a query parameter, the receiver (in this case Apigee) interprets + as "space". Which is not what we want. If I then reference that queryparam value in the AssignMessage policy I get this result:

resulting-html.png

Again I circled where SOME of the + characters should be. They are not present. The decoding causes them to be realized as space (SPC) characters. This is not an Apigee "issue". This is the definition of how query params work (see IETF RFC 1630). For any HTTP server,  the + is interpreted as SPC. 

RFC_1630 - plus.png

And there is no SPC in the base64 alphabet. Within Apigee, "Decoding" + to SPC  will result in a string that is not valid base64, which means you get no image.

On the other hand if I URI-encode the base64-encoded image, translating each + into %2B , and pass the result of THAT as a query param, I see the image correctly.

So :

  • using assignmessage with the data&colon;image/png;base64, prefix, will work. The string you pass there must be valid base64.
  • passing a valid base64 string as a queryparam, without URI-encoding it, will necessarily cause the + characters to be interpreted as SPC. Inside the Apigee proxy, or any compliant server, that string will not be a valid base64 string.
  • if you base64-encode an image, then URI-encode THAT, and pass that as a queryparam, you can do the AssignMessage exactly as I described above.

The way I base64-encoded my image:

openssl base64 -in IMAGEFILE.PNG -out image.b64

The way I URI-encoded the result of that: 

node -e 'console.log(encodeURIComponent(STRING HERE));'

So that explains what you're seeing. But this is probably all a distraction. I hope you're not passing a base64-encoded image as a queryparam to an API Proxy, except for testing.  That's not a thing that makes sense, to me.  Queryparams have a length limit.  I don't know what it is in Apigee, but it might be 16k. So you cannot pass in a very large image in a queryparam. Large things, you should post in PST bodies. And you shouldn't need to base64-encode them. 

But I think probably in your real case, you are getting the base64-encoded image from some other source.  And in that case, the queryparam plus encoding thing I described above, will not apply.

Good luck with your unusual use case.