display base64 encoded image stored in db

bino

Member
We have images that are being base64 encoded and stored in a clob field in our db. the encoding and storing of the image is working fine. If I run this test to output some of the data to a string I can see there is info stored.

Code:
<script language="speedscript">
def var v-b64-decod-str as longchar no-undo.
def var c                      as char no-undo.
def var v-str-length       as int  no-undo.
 
find record where bla blah ...
 
if avail record then
do:
   copy-lob from img.image-name to v-b64-decod-str.
   assign v-str-length = length(v-b64-decod-str).
   assign codestring = substring(v-b64-decod-str,1,512).
end.
</script>
<head>
<title>test</title>
</head>
<body>
  <textarea id="img" name="img" cols="75" wrap="VIRTUAL" rows="20" >`codestring`</textarea>
  `v-str-length`
</body>
</html>

above code works as long as I hardcode the length of the string.

But what do I do if wanted to output the full string of the base64 code? For example this will return an error. Attempt to exceed maximum size of a CHARACTER variable. (9324). I understand that the string is beyond what a char field can store so how would you output the full value of a longchar value as string?

Code:
<script language="speedscript">
def var v-b64-decod-str as longchar no-undo.
def var c                      as char no-undo.
def var v-str-length       as int  no-undo.
 
find record where bla blah ...
 
if avail record then
do:
   copy-lob from img.image-name to v-b64-decod-str.
   assign v-str-length = length(v-b64-decod-str).
   assign codestring = substring(v-b64-decod-str,1,v-str-length).
end.
</script>
<head>
<title>test</title>
</head>
<body>
  <textarea id="img" name="img" cols="75" wrap="VIRTUAL" rows="20" >`codestring`</textarea>
  `v-str-length`
</body>
</html>

Secondly, if I just wanted to display the image inline this should work but it keeps returning errors.

Code:
<script language="speedscript">
def var v-b64-decod-str as longchar no-undo.
 
find record where blah blah..
 
if avail record then
do:
     copy-lob from img.image-name to v-b64-decod-str.
end.
 
procedure output-header:
  output-content-type ("image/jpg").
  base64-decode (v-b64-decod-str).
end.
 
</script>
 
What is the purpose of using substring function?


Code:
procedure output-header:
  output-content-type ("image/jpg").
  {&OUT-LONG} base64-decode (v-b64-decod-str).
end.
 
Thanks Cecil,

You cant output the display of a lonchar value to a regular variable if its too long. I was using substring intially to just see if there was some data in the field. So I assigned a regular char var to the subtring value.

Your example will still produce the following error.

Error converting Base64 to RAW (12119).
 
I've not tested this code, so it might not work first time.

Code:
PROCEDURE output-header:
        
    /* Output the decoded base64 string into the binary format and export to the webstream...*/
    DEFINE VARIABLE mpData          AS MEMPTR   NO-UNDO.
    DEFINE VARIABLE v-b64-decod-str AS LONGCHAR NO-UNDO.
    
    SET-SIZE(mpData)= 0. /* Rule of thumb, always set the size to zero first.*/
    
    ASSIGN
        mpData = BASE64-DECODE (v-b64-decod-str).
    
    /* Optional - I use it for debugging purpose when using firefox/firebug. */
    output-http-header("X-Powered-By", SUBSTITUTE('Progress OpenEdge &1 - &2',
                                                  PROVERSION,
                                                  PROGRAM-NAME(1)).

    output-http-header("Content-Length",STRING(GET-SIZE(mpData))).
    output-content-type ("image/jpg").
    {&OUT-LONG} mpData.
    SET-SIZE(mpData)= 0.

    RETURN.
END.

Code:
<script language="speedscript">
PROCEDURE CodedBase64String:
    
    /* OUTPUT THE Encoded String to the WebStream...*/

    def var v-b64-decod-str as longchar no-undo.
    def var c                      as char no-undo.
    def var v-str-length       as int  no-undo.

    FIND record where bla blah ...
 
    IF AVAILABLE record THEN
    DO:
       COPY-LOB FROM img.image-name TO OBJECT v-b64-decod-str NO-CONVERT NO-ERROR.

       ASSIGN v-str-length = LENGTH(v-b64-decod-str).
       
       IF NOT ERROR-STATUS:ERROR AND v-str-length GT 0 THEN 
       DO:
           {&OUT-LONG} v-b64-decod-str.
       END.
    END.

    RETURN.
END PROCEDURE.
 
</script>
<head>
<title>test</title>
</head>
<body>
  <textarea id="img" name="img" cols="75" wrap="VIRTUAL" rows="20" ><!--WSS RUN CodedBase64String IN THIS-PROCEDURE. --></textarea>
  `v-str-length`
</body>
</html>
 
Cecil that worked. Thank you for your help. Part of what I was missing was
output-http-header("Content-Length",STRING(GET-SIZE(mpData))).

and the {&OUT-LONG} mpData.

Another option that I tried that worked that uses data uri's is shown below. It works great but data uri's dont work with IE7/IE6. I prefer the output header method since it seems to work in all browsers. Thanks again for your help.

Code:
<script language="speedscript">
def var v-image         as memptr   no-undo.
def var c                   as char        no-undo.
def var i                    as int          no-undo.
 
 
  find record where bla blah ...
 
  if avail record then
  do:
      {&out} '<img src="data:image/jpg;base64,'.
      copy-lob from img.image-name to v-image.
 
     do i = 1 to length(img.image-name):
       assign c = get-string(v-image, i, 1).
 
       {&out} c.
 
     end.
 
     {&out} ' width="800px" alt="image">'.
  end.
 
</script>
 
Not a problem. It gave me a little break from what I was working on a the time.
 
Back
Top