AVFP Image handler

Developer
Oct 18, 2014 at 7:42 PM
Had anyone made a image handler in AVFP? Currently images are accessed directly from client browser and I was wondering if AVFP has any image handler, so that images can be accessed from server side only. An AVFP image handler would, in my view, allow us to authenticate client requests. Not sure, how this would go with SEO or if I am making any sense. Thanks in advance.
Coordinator
Mar 1 at 4:59 PM
Digging from an old thread...

Hey Titu1,

Did you by any chance get any information on this?

I just happen to have one requirement, to show images (picture) but wanted to have some feedback on the best way of doing this. Currently the image location can be pulled from the database, I can probably copy the image to another location where it can be displayed on the browse but again looking for some ideas still.

Thank you,

Aldrin
Coordinator
Mar 1 at 5:04 PM
What kind of things should this image handler be able to do ?
Coordinator
Mar 1 at 5:49 PM
vespina wrote:
What kind of things should this image handler be able to do ?
Victor,

Not too sure what Titu1 want specifically on the Image handler but for my needs it's basically what I have mentioned earlier.

How do you handle images on your project if you have a similar functionalities that I require (where physical path is stored in one of the table i.e. C:\Images\Pictures\IMG001.JPG)
Coordinator
Mar 3 at 6:38 PM
Sorry, but I am still not clear on what are you try to do.. Do you mean to make a REST call to AVFP to return an image as a stream, the way we do with PDF files, for example ?

Victor
Coordinator
Mar 3 at 7:37 PM
Thanks for the reply Victor.

My requirement is actually more simple and I already resolved it. I just basically need to display an image stored somewhere in the clients network drive. What I did is to just copy the file to another folder inside the root of my website and it is now showing perfectly.

I do have another issue though (bumping from time to time "program is too large" issue):
https://activevfp.codeplex.com/workitem/34934

Thank you,

Aldrin
Coordinator
Mar 4 at 2:37 PM
Just created an AVFP file with this content:
<%
LOCAL cFIleName
cFileName = "e:/pvf/sos/ricardo.jpg"

oAVFP.setStreamResponse(cFileName, "image/jpeg", "inline", False) 
%>
And it showed the image in the browser (Chrome). You can also use it as an IMG src:
<img src="imghandler.avfp"/>
setStreamResponse() is part of the AVFP extension pack.


Victor
Coordinator
Mar 4 at 2:39 PM
Edited Mar 4 at 2:40 PM
This is the code for setSteamResponse, in case you want to implement this on the regular AVFP distro:
 * setStreamResponse (Method)
 * Sets a stream response
 *
 PROCEDURE setStreamResponse(pcFileName, pcContentType, pcDisposition, plDeleteFile)
  IF PCOUNT() < 4
   plDeleteFile = true
  ENDIF
  LOCAL oFSO,oFile,nSize,cStream
  oFSO = CREATEOBJECT("Scripting.FileSystemObject")
  oFile = oFSO.getFile(pcFileName)  
  nSize = oFile.Size
  cStream = CREATEBINARY(FILETOSTR(pcFileNAme))
  
  IF plDeleteFile
   ERASE (pcFileName)
  ENDIF
  
  IF LOWER(JUSTEXT(pcFileName)) == "pdf"
   pcFileName = FORCEEXT(pcFileName, "PDF")  && This is IMPORTANT for some mobile devices
  ENDIF
  pcContentType = EVL(pcContentType, "application/octet-stream")
  pcDisposition = EVL(pcDisposition, "attachment")
  
  oResponse.Clear()
  oResponse.Buffer = .T.
  oResponse.contentType = pcContentType
  oResponse.AddHeader("Pragma","public")
  oResponse.AddHeader("Cache-Control","no-cache")
  oResponse.AddHeader("Content-Type",pcContentType)
  oResponse.AddHeader("Content-Length",ALLTRIM(STR(oFile.Size)))  
  oResponse.AddHeader("Content-Disposition", STRCONV(pcDisposition + [; filename=] + JUSTFNAME(pcFileName),9))
  oResponse.AddHeader("Content-Transfer-Encoding","binary")
  oResponse.CharSet = "UTF-8"
  oResponse.BinaryWrite(cStream)
  oResponse.End()
  oResponse.Flush() 
 ENDPROC 
Coordinator
Mar 4 at 3:55 PM
Edited Mar 4 at 4:14 PM
Hi Victor,

I just tested the code above but I can't seem to have this working on my end. (No image being displayed)
  • Added procedure setStreamResponse in the MAIN.PRG
  • created _imagetest.avfp with contents below:
   <img src="imghandler.avfp"/>
   <img src="<%=JUSTPATH(oProp.ScriptPath)+[/imghandler]+oProp.Ext%>"/>
Both image is not showing.
  • created imghandler.avfp with contents below:
<%
LOCAL cFIleName
cFileName = "D:\Data\patpics\e09300_20160303143325.jpg"
oAVFP.setStreamResponse(cFileName, "image/jpeg", "inline", False) 
%>
Anything that I'm missing?
Coordinator
Mar 4 at 4:38 PM
Figured it out... I just have to remove oAVFP in the imghandler.avfp.

Thanks again.
Coordinator
Mar 4 at 4:54 PM
Glad it worked!

oAVFP is a reference to the new AVFP helper class, that contains the setStreamRespose method. For regular AVFP implementation, you must do what you did: add setStreamResponse as a procedure in MAIN and then call it as a regular proc, without the oAVFP. prefix.

This setStreamResponse can be used to return any kind of binary content, like PDF, XLS, TXT, JavaScript code, etc.


Victor
Coordinator
Jun 2 at 4:44 PM
Edited Jun 2 at 4:53 PM
Victor,

With regards to the setStreamResponse() above, how do you deal with multiple images being displayed in the same page?
<%
for i = 1 to 3
m.lsimagepath = "C:\image\customer" + str(i) + ".jpg"
oSession.VALUE("customerpic",m.lsimagepath)
%>
the + should just be a plus sign.
<p><%=justfname(oSession.VALUE("customerpic"))%></p>  
<img src="imghandler.avfp"/>
<%endfor%>
for the imghandler.avfp:
<%
oAVFP.setStreamResponse(oSession.VALUE("customerpic"), "image/jpeg", "inline", False) 
%>
In this example, there will be 3 images being displayed but it would be the same ( in this case a C:\image\customer3.jpg is being shown). My P tag will shows 3 different file name (i.e. customerpic1.jpg; customerpic2.jpg; customerpic3.jpg respectively)
Coordinator
Jun 7 at 3:48 PM
Edited Jun 7 at 3:54 PM
The problem I see is that you are storing the file names in the same session variable, therefore, only the last value will be stored in the sessiond data. It seems to me that the code should goes like this:
<%
for i = 1 to 3
 m.lsimagepath = "C:\image\customer" +  allt(str(i)) + ".jpg" 
 oSession.VALUE("customerpic" +  allt(str(i)),m.lsimagepath)
endfor
%>
and then in the AVFP page:
<%
for i = 1 TO 3
 oAVFP.setStreamResponse(oSession.VALUE("customerpic"+allt(str(i)), "image/jpeg", "inline", False) 
endfor
%>
Victor
Coordinator
Jun 7 at 5:08 PM
Good point for the variable, but I don't think it will work still since my image src is always
<img src="imghandler.avfp"/>
hence it will still show the last image no matter what.
Coordinator
Jun 15 at 3:25 PM
Then do this:
<img src="imghandler.avfp?id=1" />
<img src="imghandler.avfp?id=2" />
<img src="imghandler.avfp?id=3" />
And in your imghandler.avfp:
<%
oAVFP.setStreamResponse(oSession.VALUE("customerpic" + AVGet("id")), "image/jpeg", "inline", False)
%>
Victor