Saving Images

This Q&A forum allows users to post and respond to "How Do I Do ....." questions. Please do not use to report (suspected) errors - you must use your regional help desk for this. The information contained in this forum has not been validated by LANSA and, as such, LANSA cannot guarantee the accuracy of the information.
Post Reply
User avatar
lawingo
Posts: 51
Joined: Fri Dec 04, 2015 6:41 am

Saving Images

Post by lawingo » Thu Jun 08, 2017 12:43 am

I have a project where a User wants to take a photo with his/her iPad that is associated with an order #. Easy enough I have created a Web Page that allows the user to access the camera and/or the photo gallery.

I would like to save this image somewhere on the network so that I can make use of it from another application. This is my first project of this type and my question is how is the best way to do this? I believe I want to either save the image into the DB as a Blob or save the image to a pre-determined folder on my network and save the file location in the file.

What is the best method or is there another way of going about this? Thanks for your help in Advance. - Chad -

HamadSheikh
Posts: 27
Joined: Fri Mar 18, 2016 3:49 am
Location: USA
Contact:

Re: Saving Images

Post by HamadSheikh » Thu Jun 08, 2017 2:42 am

By storing the image into the database, it becomes easier to manage the data as a single entity. However, you need to consider the volume and disk space requirements too, as images can easily take up a lot of space over time. Perhaps you can cleanse the database of old records by archiving them into separate a separate database or table?

Also, you have to build your database such that the BLOB fields do not get read for each I/O you perform, when retrieving the rest of the record (excluding the BLOB) i.e. have the BLOB field in a separate file that is accessed only when needed.

By storing images into a windows folder, you have to worry about user permissions, OS and Antivirus security requirements etc.

IMO the best approach is to test this out in your environment first, before making a decision. I personally prefer storing images as BLOBs. Especially since (in the future) you will have AI techniques of performing data analysis on the images too.

User avatar
lawingo
Posts: 51
Joined: Fri Dec 04, 2015 6:41 am

Re: Saving Images

Post by lawingo » Thu Jun 08, 2017 4:17 am

Hamad,

Thanks for your reply. I have never worked with Blobs before. Looking at the Documentation - most of the examples are using the PRIM_WEB.FilePicker. Do you have any examples using the Camera Control Widget? My users will be taking a Photo not necessarily picking an existing photo. For Example here is what I have:

Define Field(#W_BLOBH) Type(*STRING)

Evtroutine Handling(#CameraControl.Completed) Base64data(#base64) File(#file)

#Image1.FileName := #base64
#W_BLOBH := #base64
Endroutine

I can not move the #base64 or the #file or even the #image1.FileName return data into the Blob field. The IDE tells me its not compatible so I have used a String Field(#w_blobh). I pass this field back to my Server Module and then process it this way:


Srvroutine Name(InsertWBEP)
List_Map For(*INPUT) List(#L_WBEP) Parameter_Name(TheList)

Field_Map For(*OUTPUT) Field(#WBEPID) Parameter_Name(id)
Field_Map For(*OUTPUT) Field(#W_STATUS) Parameter_Name(Status)

Get_Entry Number(1) From_List(#L_WBEP)

#WBEPID := 0
#WBEPIMG := #W_BLOBH
Insert Fields(#WBEPID #WBEPDLNO #WBEPIMG #WBEPDS #WBEPACNO #WBEPDLNM) To_File(WBEP) Io_Status(#W_STATUS) Io_Error(*NEXT) Val_Error(*NEXT) Return_Rrn(#PRIFILRRN)

Fetch Fields(#WBEPID) From_File(WBEP) Io_Error(*NEXT) Val_Error(*NEXT) With_Rrn(#PRIFILRRN)
Endroutine

However, I receive a Validation Error Return code when attempting to Insert the Record. If I comment (#WBEPIMG := #W_BLOBH) then the Validation Error goes away.

Any help is greatly appreciated.
Thanks -Chad-

caseywhite
Posts: 100
Joined: Thu May 26, 2016 1:17 am

Re: Saving Images

Post by caseywhite » Sat Jun 10, 2017 9:15 am

The File Picker is nice in that you don't have to run it in LANSA Mobile and the coding is easier. But it seems like you don't know if the picture was taken portrait so you would have to give the user the option to rotate the picture. But since it supports BLOB the coding of passing the BLOB field to the server module and reading the BLOB field is really easy. So it could be worth considering the file picker.

If you want to use the camera widget keep in mind this has to run in LANSA Mobile, which is a free app you can download to your phone run run any WAM or VL Web URL. In the IDE Click on Home and Look at the Samples and Examples. Look Camera on the left hand side. There is a nice example there. The Camera sample and example doesn't show how to save the data, which isn't a BLOB, like in the Filepicker example. It is a base 64 string that is be VERY long (e.g. over 1 million bytes). So just convert that to a CLOB in the server module. You can't do the conversion in the web page. Easiest way to do the conversion is in your web page chop up the base 64 string into 65000 byte string fields and put that into a list which you will then pass to your server module.

In your server module the trick to getting the list into a CLOB field is to use the stream file BIFs like this.
The IMG64X field is string 65000. The list is a single field list with the field IMG64X IMG field is CLOB.

Code: Select all

Use Builtin(STM_FILE_OPEN) With_Args('C:\temp\imagefile.txt' 'Write LineTerminator=NONE') To_Get(#W_FileNumber)

Selectlist Named(#IMG64List)
Use Builtin(STM_FILE_WRITE) With_Args(#W_FileNumber #IMG64X)
Endselect
Use Builtin(STM_FILE_CLOSE) With_Args(#W_FileNumber)

#IMG := 'C:\temp\imagefile.txt'
Insert Fields(#STD_NUM #IMG) To_File(IMGS)
Use Builtin(OV_FILE_SERVICE) With_Args('REMOVE_FILE' 'C:\temp\imagefile.txt')
When reading the file to show to the user just create a list to pass back from the server module. Below is the server module code.

Code: Select all

Fetch Fields(#IMG) From_File(IMGS) With_Key(#STD_NUM)
If_Status Is(*OKAY)
Use Builtin(STM_FILE_OPEN) With_Args(#IMG.FileName 'Read') To_Get(#W_FileNumber)
Dountil Cond((#W_ReturnCode <> 'OK') And (#W_ReturnCode <> 'OV'))
Use Builtin(STM_FILE_READ) With_Args(#W_FileNumber) To_Get(#IMG64X #W_ReturnCode)
Add_Entry To_List(#IMG64List)
Enduntil
Use Builtin(STM_FILE_CLOSE) With_Args(#W_FileNumber)
Endif
In your web page just concatenate all the list entries to create the base64 string that the camera widget needs.

caseywhite
Posts: 100
Joined: Thu May 26, 2016 1:17 am

Re: Saving Images

Post by caseywhite » Wed Jun 14, 2017 3:34 am

If you want to show your images in a list when reading the CLOB data from the server then you could use this technique. Base64 is just a PRIM_ALPH.

Code: Select all

* Get data from your server module, which will return a list without the image data and a second list with just a key field and the CLOB data split up into 65000 chunks.  
SelectList Named(#IMGSListHeader)
Add_Entry To_List(#List1)

* Set the image
#Base64 := *null
Selectlist Named(#IMGSListImages) Where(#FieldInSecondListReturnedFromServerModule = #ImageKeyFromIMGSListHeader)
#Base64 += #IMG64X
Endselect
#ColumnImage1.CurrentItem.Image <= #sys_appln.CreateBitmap( ("data:image/png;base64," + #Base64) )
EndSelect

Post Reply