For this article we will use the Biolife table that can be found in the DBDEMOS Alias that comes standard with Delphi.
Starting the Project
In the OnAction event of the waFish action item, type the following code:
procedure TWebModule1.WebModule1waFishAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin try with Query1 do begin Close; SQL.Clear; SQL.Add('SELECT BIOLIFE."Species No", Common_Name FROM BIOLIFE'); Open; Response.Content := Response.Content '<h2>The various species of Fish</h2><br>' #13#10 'Click on the hyperlinks below to see the picture of the given species<P>'; while not Eof do begin Response.Content := Response.Content Format('<a href="%s/%s?No=%s">%s</a><br>' #13#10, [Request.ScriptName, 'SendImage', Fields[0].AsString, Fields[1].AsString]); Next; end; { while not Eof } Close; end; { with Query1 do } except on E : Exception do Response.Content := '<b>ERROR</b><br>' #13#10 E.Message; end; end;
<A HREF="/scripts/Fish.exe/SendImage?No=90030">Red Emperor</A><BR>
This is standard HTML. Notice here that the /SendImage action is called sending it a parameter -"No=90030". We will "extract" the value of "No" from this to use in the next query that we will build dynamically in the /SendImage action's OnAction event.
The /SendImage action's OnAction event looks like this :
procedure TWebModule1.WebModule1waSendImageAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var JPEG : TJPEGImage; MemStrm: TMemoryStream; Bitmap : TBitmap; begin { In this action event, I "extract" the Species No parameter from the QueryFields property of the Request object and use that to get the image from the table. Then I stream out the image as a Jpeg image } try JPEG := TJPEGImage.Create; MemStrm := TMemoryStream.Create; Bitmap := TBitmap.Create; try with Query1 do begin Close; SQL.Clear; SQL.Add('SELECT Graphic FROM BIOLIFE'); SQL.Add('WHERE BIOLIFE."Species No" = :LastName'); Params[0].AsInteger := StrToInt(Request.QueryFields.Values['No']); Open; { Assign the image from the database to a Bitmap object since the field type is a TGraphicField.} Bitmap.Assign(FieldByName('GRAPHIC')); JPEG.Assign(Bitmap); JPEG.SaveToStream(MemStrm); MemStrm.Position := 0; { The content type needs to be set !! } Response.ContentType := 'image/jpeg'; Response.ContentStream := MemStrm; end; finally JPEG.Free; { Do not Free MemStrm. The Web server will take care of it. } Bitmap.Free; end; except on E : Exception do Response.Content := '<b>ERROR</b><br>' #13#10 E.Message; end; end;
The code above is commented to explain what is going on. If one had instantiated the fields of the Query object than one could have assigned the field object (for the image field) directly to the bitmap. The code for that would look like Bitmap.Assign(Query1Graphic). In this particular example, you shouldn't/can't instantiate the field object explicitly since we use the same Query object for different SQL queries that return different sets of fields.
The ContentType property of the Response object can be set to 'image/gif' if you want to send gif images. The various ContentType values can be found in the HTTP specifications.
Another interesting Project is the next project where we reduce the image size just before we send the image. This technique is very useful and effective is real world ISAPI application development. Check it out.