Saturday, July 31, 2010

A SQL Anywhere Web Service for Displaying Images

Most SQL Anywhere web services are devoted to returning HTML, XML and other text to the client, but they work just fine for binary data too... like images.

Code first, explanation later...


Here's a web service that returns an image to the browser; all it has to do is set the "Content-Type" and return the image as a single-row single-column result set:
1
<br>CREATE SERVICE rroad_display_image TYPE 'RAW'<br>   AUTHORIZATION OFF USER DBA_image<br>   AS CALL rroad_display_image ( :f );<br><br>CREATE PROCEDURE rroad_display_image (<br>   IN @p_file_name VARCHAR ( 100 ) )<br>BEGIN<br><br>CALL dbo.sa_set_http_header( 'Content-Type', 'image/gif' );<br><br>SELECT file_image<br>  FROM rroad_image<br> WHERE file_name = @p_file_name;<br><br>END; -- rroad_display_image<br>

In this case, the images are stored in a table, inside the same database where the code for the web service runs:
1
<br>CREATE TABLE rroad_image (<br>   file_name  VARCHAR ( 100 ) NOT NULL,<br>   file_image LONG BINARY NOT NULL,<br>   PRIMARY KEY ( file_name ) );<br><br>INSERT rroad_image VALUES ( 'help.gif',      dbo.xp_read_file ( 'images\\help.gif' ) );<br>INSERT rroad_image VALUES ( 'favicon_m.ico', dbo.xp_read_file ( 'images\\favicon_m.ico' ) );<br>

Here's a snippet of code from a "calling" web service called rroad_history_menu that needs to display an image named "help.gif". The <IMG SRC="rroad_display_image?f=help.gif"... tag passes the file name help.gif to the rroad_display_image web service via the parameter named f. When the web page created by rroad_history_menu hits the browser, that IMG tag is evaluated and the rroad_display_image web service is called to return the image:
1
<br>CREATE SERVICE rroad_history_menu TYPE 'RAW'<br>   AUTHORIZATION OFF USER DBA_history_menu<br>   AS CALL rroad_history_menu ( :z1,   -- session id1<br>                                :zi,   -- sampling id <br>                                :sn ); -- sample set number <br><br>CREATE PROCEDURE rroad_history_menu (<br>   IN @z1              LONG VARCHAR DEFAULT NULL,     -- session id1<br>   IN @zi              LONG VARCHAR DEFAULT NULL,     -- sampling id<br>   IN @sn              LONG VARCHAR DEFAULT NULL )    -- sample set number<br>   RESULT ( html_output LONG VARCHAR )<br>BEGIN<br><br>SELECT STRING ( <br>   '<HTML>',<br><br>   ...<br><br>   --------------------------------------------------<br>   -- Menu: Line 1: Help icon and link<br><br>   '<A HREF="rroad_help_frame?f=foxhound_history#menu" ',<br>      'TARGET="help_frame" TITLE="Show a description of this menu area in the Help frame">',<br>      '<IMG SRC="rroad_display_image?f=help.gif" BORDER="0" WIDTH="16" HEIGHT="16" HSPACE="0" VSPACE="0" ',<br>      'STYLE="vertical-align: text-bottom; border-bottom: 1px solid blue"> Help</A>    ',<br><br>   ...<br><br>   '</HTML>' );<br><br>END; -- rroad_history_menu<br>

There are several copies of help.gif displayed by rroad_history_menu, one for each context-sensitive Help area; look for the little blue "?" marks:



Here's another snippet of code that needs to return a "favicon" to the browser. When the web page created by the SELECT statement hits the browser, the <LINK ... HREF="rroad_display_image?f=favicon_m.ico" tag tells the browser to turn around and call rroad_display_image to get favicon_m.ico:
1
<br>   CALL dbo.sa_set_http_header( 'Content-Type', 'text/html' );<br><br>   SELECT STRING ( <br>      '<HTML>',<br>      '<HEAD>',<br>      ...<br>      '<LINK REL="SHORTCUT ICON" HREF="rroad_display_image?f=favicon_m.ico" />',<br>      '</HEAD>',<br>      ...<br>      '</HTML>' );<br>

Here's what favicon_m.ico looks like on the Firefox tab bar (look for the "M"):



The observant reader will notice that it doesn't seem to matter that 'Content-Type' is set to 'image/gif' in the first snippet of code... it works fine for *.ico files, and *.jpg too. Web browsers are wonderfully robust, they really don't mind if your HTML is a bit shaky... even if you commit heresies like forgetting to code the <BODY> tag. It's a good thing HTML came along before XML and all those Politically Correct Programmers who insist <P> without </P> is a crime against humanity, otherwise nobody would get any work done :)

No comments: