Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 8 of 8 total
Thread load Image on grid click
Wed, Oct 12 2016 4:00 AMPermanent Link

kamran

Hi

Using EWB 2.05b4.

1. I have a TGrid, a TImage defined on a form
2.Product data table is in a local folder: "c:\pcs"
3.Images are in  a local folder: "c:\pcs"

e.g. "productimage1.png", "productimage2.png" etc...

4.*same* folders will be used on the WEB server as well when the site is live.


I have data populated in the TGrid with product code and description.

When i do a "OnClick" on the TGrid I have the following code to display the image


***********************************************************
procedure TMainForm.EquipmentGridClick(Sender: TObject);
begin
 // load the image into timage according to the product code selected from grid
 EquipmentPicture.Background.Image.Name:='c:\pcs\'+PCSDataBaseForm.Product.Columns['PRODUCT_SELL_CODE'].AsString+'\.png';
end;
***********************************************************

After the click event, I would have expected the image to be shown at this point.

5. Clearly there is something I have missed..

6. TImage has a URL property ..

Does that not essentially perform the same thing as assigning the Name property?
e.g tell the system what to load into it and from where ?
Should I be using the URL property instead?

7. How would the URL property of TImage be populated / assigned to achieve the same ?

8. Assigning a image.name at design time works ok; but *not* when i try to change it to a new image name in code.


Kind regards


Kamran
Wed, Oct 12 2016 9:21 AMPermanent Link

Raul

Team Elevate Team Elevate

On 10/12/2016 4:00 AM, kamran wrote:
> 1. I have a TGrid, a TImage defined on a form
> 2.Product data table is in a local folder: "c:\pcs"
> 3.Images are in  a local folder: "c:\pcs"

You must host data thru a web server - you cannot load it from local
disk using file paths. You need to run a web server and configure it to
server the files from the folder - you would access it using proper URL
though.

See another thread right here yesterday that discussed grid and image
loading and sample URLs
(http://www.elevatesoft.com/forums?action=view&category=ewb&id=ewb_general&page=1&msg=11109)

> 4.*same* folders will be used on the WEB server as well when the site is live.

Does not work like this and must be properly served by the web server -
see point above.


Raul
Wed, Oct 12 2016 11:32 AMPermanent Link

kamran

Hi Raul

Thanks for the response.

So as I understand it you are saying that I need to issue a server request / get  with the URL for each image I need to display when the onclick event is fired.

1. Have I understood that right?

2. Is that method efficient ?

3. Is it better / more efficient to store the images as a blob in the actual product table ?

Kind Regards

Kamran


Raul wrote:

On 10/12/2016 4:00 AM, kamran wrote:
> 1. I have a TGrid, a TImage defined on a form
> 2.Product data table is in a local folder: "c:\pcs"
> 3.Images are in  a local folder: "c:\pcs"

You must host data thru a web server - you cannot load it from local
disk using file paths. You need to run a web server and configure it to
server the files from the folder - you would access it using proper URL
though.

See another thread right here yesterday that discussed grid and image
loading and sample URLs
(http://www.elevatesoft.com/forums?action=view&category=ewb&id=ewb_general&page=1&msg=11109)

> 4.*same* folders will be used on the WEB server as well when the site is live.

Does not work like this and must be properly served by the web server -
see point above.


Raul
Wed, Oct 12 2016 11:55 AMPermanent Link

Raul

Team Elevate Team Elevate

On 10/12/2016 11:32 AM, kamran wrote:
> So as I understand it you are saying that I need to issue a server request / get  with the URL for each image I need to display when the onclick event is fired.

Generally yes - but if you are using EWB dataset functionality then most
of this already handled for you so as long as proper URLs are used this
is automatic.

Look at "databound" example either here
(http://www.elevatesoft.com:8081/databound/databound.html) or it's also
included with EWB so you can see what's happening.

The image here is liked to the dataset so code does not need to do
anything to load the image - it's already handled by EWB framework.

> 1. Have I understood that right?

Generally yes but EWB can auomate it


> 2. Is that method efficient ?

In what way? At some point it needs to be downloaded from server so
there will be a need  for that. however browsers are very capable these
days so unless you have a very slow internet (or very large images) this
should not be a problem.


> 3. Is it better / more efficient to store the images as a blob in the actual product table ?

In terms of efficiency there is not a lot of difference since the same
amount data (image content) needs to be downloaded. If you do store it
as blob then you do need to server it back properly -EWB web server can
do that for you but if you write your own back end then you need to
handle this.

Having actual images on disk and served as fixed URLs might be somewhat
more efficient since browser might be able to cache it better.

I would suggest do whatever is better from your app design perspective.

Raul
Thu, Oct 13 2016 6:37 AMPermanent Link

kamran

Hi Raul

So I decided to load images from web *server disk* - as you say it is probably more efficient.

My attempt at doing this is shown below.

I searched the forum but could not see any direct example I could follow easily

I define a TServerRequest and then execute it on a grid click.

the images are stored on the web server as .png files and referenced by the product code name

Here is my code:

*******************************************************************************
procedure TMainForm.EquipmentGridClick(Sender: TObject);
begin
 // load the image into timage according to the selected product code name
  with GetPictureRequest do
     begin
       RequestHeaders.Add('Content-Type: image/png');
       RequestHeaders.Add('Content-Length: '+ IntToStr(Length(GetPictureRequest.RequestContent.Text)));
       URL:='http://www.domainname.com:8080/pcs';
       Execute;
     end;
end;

procedure TMainForm.GetPictureRequestComplete(Request: TServerRequest);
begin
 if (Request.StatusCode=200) then
 EquipmentPicture.Background.Image.Name:=PCSDataBaseForm.Product.Columns['PRODUCT_SELL_CODE'].AsString+'\.png'
 else MessageDlg('Error loading product image','Error',mtError,[mbOk],mbOk);
end;
*******************************************************************************************

Am clearly doing something wrong here as it does not work for me.

So how can I get it to work?

Thanks

Kamran
Thu, Oct 13 2016 8:56 AMPermanent Link

Raul

Team Elevate Team Elevate

On 10/13/2016 6:37 AM, kamran wrote:
> My attempt at doing this is shown below.
> I searched the forum but could not see any direct example I could follow easily

Did you look at databound that i referenced below - it includes exactly
what you require.

> I define a TServerRequest and then execute it on a grid click.

You do not need server request just to load an image into a TImage if
that image is accessible by URL.

> the images are stored on the web server as .png files and referenced by the product code name

great.


>   // load the image into timage according to the selected product code name
>    with GetPictureRequest do
>       begin
>         RequestHeaders.Add('Content-Type: image/png');
>         RequestHeaders.Add('Content-Length: '+ IntToStr(Length(GetPictureRequest.RequestContent.Text)));

As i said you do not need this but why are you adding these headers ?

Headers are supplied by the server if it returns the document so these
don't do anything.


>         URL:='http://www.domainname.com:8080/pcs';

This is not a valid URL for an image : proper URL path would be
something like "http://www.domainname.com:8080/pcs/product1.jpg" or in
your case it should be :

URL := 'http://www.domainname.com:8080/pcs/' +
PCSDataBaseForm.Product.Columns['PRODUCT_SELL_CODE'].AsString + '.png';


However if you already have a TImage then TImage can natively load the
image thru the URL so you do not need a TServerRequest.

for example i have number of images on the web server and they are
accessible as : "http://localhost:8080/p/a1.jpg,
"http://localhost:8080/p/a2.jpg" etc.

and my Grid has a column "PicNmae" for image filename (this has data
like "a1.jpg")

Loading the image would simply involve

procedure TForm1.Grid1Click(Sender: TObject);
begin
  Image1.URL := 'http://localhost:8080/p/' +
MyData.Columns['PicName'].AsString;
end;


however i recommend you use Rowchanged instead so grid drives the image
automatically whenever selected row changes:

procedure TForm1.Grid1RowChanged(Sender: TObject);
begin
   Image1.URL := 'http://localhost:8080/p/' +
MyData.Columns['PicName'].AsString;
end;




If you want this to work even more automatically you can do what
databound example does and actually return a relative URL for the image
as part of the dataset - however this is tied to datbase BaseURL so you
would need to host your data and images from the same URL right now (or
do some framework hacking to be able to override timage baseurl to be
different than database one).

Raul
Thu, Oct 13 2016 10:44 AMPermanent Link

kamran

Hi

*Thank you* kindly for clarifying this.

It all makes sense now.

I just realized that *not all*  images are in .png format.

1. I suppose there is a way to find out what the file is before loading?

2. Would that be by checking the "content type"  in the header?

Regards

Kamran

Raul wrote:

On 10/13/2016 6:37 AM, kamran wrote:
> My attempt at doing this is shown below.
> I searched the forum but could not see any direct example I could follow easily

Did you look at databound that i referenced below - it includes exactly
what you require.

> I define a TServerRequest and then execute it on a grid click.

You do not need server request just to load an image into a TImage if
that image is accessible by URL.

> the images are stored on the web server as .png files and referenced by the product code name

great.


>   // load the image into timage according to the selected product code name
>    with GetPictureRequest do
>       begin
>         RequestHeaders.Add('Content-Type: image/png');
>         RequestHeaders.Add('Content-Length: '+ IntToStr(Length(GetPictureRequest.RequestContent.Text)));

As i said you do not need this but why are you adding these headers ?

Headers are supplied by the server if it returns the document so these
don't do anything.


>         URL:='http://www.domainname.com:8080/pcs';

This is not a valid URL for an image : proper URL path would be
something like "http://www.domainname.com:8080/pcs/product1.jpg" or in
your case it should be :

URL := 'http://www.domainname.com:8080/pcs/' +
PCSDataBaseForm.Product.Columns['PRODUCT_SELL_CODE'].AsString + '.png';


However if you already have a TImage then TImage can natively load the
image thru the URL so you do not need a TServerRequest.

for example i have number of images on the web server and they are
accessible as : "http://localhost:8080/p/a1.jpg,
"http://localhost:8080/p/a2.jpg" etc.

and my Grid has a column "PicNmae" for image filename (this has data
like "a1.jpg")

Loading the image would simply involve

procedure TForm1.Grid1Click(Sender: TObject);
begin
  Image1.URL := 'http://localhost:8080/p/' +
MyData.Columns['PicName'].AsString;
end;


however i recommend you use Rowchanged instead so grid drives the image
automatically whenever selected row changes:

procedure TForm1.Grid1RowChanged(Sender: TObject);
begin
   Image1.URL := 'http://localhost:8080/p/' +
MyData.Columns['PicName'].AsString;
end;




If you want this to work even more automatically you can do what
databound example does and actually return a relative URL for the image
as part of the dataset - however this is tied to datbase BaseURL so you
would need to host your data and images from the same URL right now (or
do some framework hacking to be able to override timage baseurl to be
different than database one).

Raul
Thu, Oct 13 2016 11:41 AMPermanent Link

Raul

Team Elevate Team Elevate

On 10/13/2016 10:44 AM, kamran wrote:
> I just realized that *not all*  images are in .png format.

Are they valid image types to be displayed by the browser (jpg, gif etc) ?

If so then as long as your URL is correct image is still properly shown.

Your challenge is that how would you know what the correct URL is ?
(since you cannot use the PRODUCT_SELL_CODE + '.png' anymore).

One option is to add a column in your table that either stores the
actual file name (i.e. PRODUCT_SELL_CODE + extension like you did) or at
least stores image type or extension and then you can build this in EWB
code.

I like storing actual file names with extension since if type of jpg
would the extension be ".jpg" or ".jpeg" ?


> 1. I suppose there is a way to find out what the file is before loading?
> 2. Would that be by checking the "content type"  in the header?

Not this way - in order to do this you would need to know the URL and if
you know the url then just load it into timage and if its supported
image will appear.

Raul

Image