Lazarus

Programming => Graphics and Multimedia => Graphics => Topic started by: gromar on March 12, 2015, 01:09:36 pm

Title: Changing pictures after reaching value on the TImage component
Post by: gromar on March 12, 2015, 01:09:36 pm
Hello!

I'd like to change picture loaded into Image1 - from one called greenseat.gif to second called redseat.gif after the Integer value will be <=20.

For example: I have an icon of green seat in bus and it shows number of seat which are free (overall there will be 30 seats), if 20 ppl will sit on those seats the icon should change colour to red (it should load the different image representing red seat).

Is there any way to do it? Thank you in advance for any tips : )
Title: Re: Changing pictures after reaching value on the TImage component
Post by: mm7 on March 12, 2015, 05:18:13 pm
var gifR,gifG : TGIFImage;
...
gifR:=TGIFImage.Create;
gifR.LoadFromFile('redseat.gif');
gifG:=TGIFImage.Create;
gifG.LoadFromFile('grnseat.gif');
....
if seats <= 20
then Image1.Picture.Assign(gifR);
else Image1.Picture.Assign(gifG);
Title: Re: Changing pictures after reaching value on the TImage component
Post by: Basile B. on March 12, 2015, 06:10:19 pm
not good, you create two object instances while only one is needed. And there is a syntax error (semi-colon after the if then statement)

Code: [Select]
var
  gif: TGIFImage;
const
  names: array[boolean] of string = ['redseat.gif', 'grnseat.gif'];
...
gif := TGIFImage.Create;
gif.LoadFromFile(names[seats <= 20]);
Image1.Picture.Assign(gif);
...
Title: Re: Changing pictures after reaching value on the TImage component
Post by: mm7 on March 12, 2015, 06:25:52 pm
 :D
>not good, you create two object instances while only one is needed.
And I even do not destroy them after!

>And there is a syntax error (semi-colon after the if then statement)
And there is another syntax error : .... - Dot found when END is expected :)

By the way,
Code: [Select]
names[seats <= 20]Uses True and False as numeric indexes 1 and 0.
Not very good from Pascal's concept of strict types . It is too C-ish :\
:)
Title: Re: Changing pictures after reaching value on the TImage component
Post by: engkin on March 12, 2015, 07:06:47 pm
I must be missing something here. Why not call Image1.Picture.LoadFromFile directly instead of using TGIFImage?
Title: Re: Changing pictures after reaching value on the TImage component
Post by: wp on March 12, 2015, 07:16:32 pm
Quote
const
  names: array[boolean] of string = ['redseat.gif', 'grnseat.gif'];
....
Uses True and False as numeric indexes 1 and 0.
Not very good from Pascal's concept of strict types . It is too C-ish :\

Nothing is "C-ish" with this declaration. The names array is declared to use boolean as index. Where did you read that an array index can only be an integer in Pascal?
Title: Re: Changing pictures after reaching value on the TImage component
Post by: mm7 on March 12, 2015, 08:03:17 pm
sorry, I missed that part.
Title: Re: Changing pictures after reaching value on the TImage component
Post by: mm7 on March 12, 2015, 08:09:58 pm
I must be missing something here. Why not call Image1.Picture.LoadFromFile directly instead of using TGIFImage?

I did not try. GIF is not documented here.
http://lazarus-ccr.sourceforge.net/docs/lcl/graphics/tpicture.html
http://lazarus-ccr.sourceforge.net/docs/lcl/graphics/tbitmap.html
Quote
TBitmap is the data of an image. The image can be loaded from a file, stream or resource in .bmp (windows bitmap format) or .xpm (XPixMap format)
Title: Re: Changing pictures after reaching value on the TImage component
Post by: engkin on March 12, 2015, 08:24:31 pm
The description in TPicture.LoadFromFile (http://lazarus-ccr.sourceforge.net/docs/lcl/graphics/tpicture.loadfromfile.html) page:
Quote
LoadFromFile - Reads a picture from disk. The TGraphic class created is determined by the file extension of the file.

And the source code (http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/lcl/include/picture.inc?view=markup&root=lazarus):
Code: [Select]
constructor TPicFileFormatsList.Create;
begin
  inherited Create;
  // add by priority of use in LCL/IDE
  Add(TPortableNetworkGraphic.GetFileExtensions, rsPortableNetworkGraphic, TPortableNetworkGraphic);
  Add(TPixmap.GetFileExtensions, rsPixmap, TPixmap);
  Add(TBitmap.GetFileExtensions, rsBitmaps, TBitmap);
  Add(TCursorImage.GetFileExtensions, rsCursor, TCursorImage);
  Add(TIcon.GetFileExtensions, rsIcon, TIcon);
  Add(TIcnsIcon.GetFileExtensions, rsIcns, TIcnsIcon);
  Add(TJpegImage.GetFileExtensions, rsJpeg, TJpegImage);
  Add(TTiffImage.GetFileExtensions, rsTiff, TTiffImage);
  Add(TGIFImage.GetFileExtensions, rsGIF, TGIFImage);   //<------------- Here we go
  Add(TPortableAnyMapGraphic.GetFileExtensions, rsPortablePixmap, TPortableAnyMapGraphic);
end;
Title: Re: Changing pictures after reaching value on the TImage component
Post by: mm7 on March 12, 2015, 10:00:50 pm
Well, in code there it is. But not in official docs. In other systems such thing is called "undocumented feature" and it is not recommended to rely on it and use in programs, because it can change anytime.
I am new to Lazarus, how is it here? Should one rely on a feature that is not yet officially documented?
Title: Re: Changing pictures after reaching value on the TImage component
Post by: engkin on March 12, 2015, 10:18:50 pm
What exactly in the documentation  (http://lazarus-ccr.sourceforge.net/docs/lcl/graphics/tpicture.loadfromfile.html)gave the impression that Image1.Picture.LoadFromFile will not work for *.gif images?
Title: Re: Changing pictures after reaching value on the TImage component
Post by: gromar on March 13, 2015, 01:21:22 pm
Hello again,

I've made it - it works like in example I wrote. Next thing I'd like to achieve is to make proper counters which will show separately how many seats are free (counting green images of seats) or not (red image of seat). So far my code looks like this (I'm testing it with one seat):
Code: [Select]
procedure TForm1.Edit1Change(Sender: TObject);
var gifR,gifG : TGIFImage;
  siedzenie : integer;
begin
    siedzenie := Length(Edit1.Text);
    Label1.Caption := IntToStr(siedzenie);

gifR:=TGIFImage.Create;
gifR.LoadFromFile('red.gif');
gifG:=TGIFImage.Create;
gifG.LoadFromFile('grn.gif');
    if siedzenie <= 20 then Image1.Picture.Assign(gifG)
    else Image1.Picture.Assign(gifR);
end;
Title: Re: Changing pictures after reaching value on the TImage component
Post by: mm7 on March 13, 2015, 03:43:42 pm
What exactly in the documentation  (http://lazarus-ccr.sourceforge.net/docs/lcl/graphics/tpicture.loadfromfile.html)gave the impression that Image1.Picture.LoadFromFile will not work for *.gif images?

GIF is not there.
And not here as well. http://lazarus-ccr.sourceforge.net/docs/lcl/graphics/tpicture.html
Other formats are.
Title: Re: Changing pictures after reaching value on the TImage component
Post by: engkin on March 13, 2015, 04:39:48 pm
What exactly in the documentation  (http://lazarus-ccr.sourceforge.net/docs/lcl/graphics/tpicture.loadfromfile.html)gave the impression that Image1.Picture.LoadFromFile will not work for *.gif images?

GIF is not there.
And not here as well. http://lazarus-ccr.sourceforge.net/docs/lcl/graphics/tpicture.html
Other formats are.

Neither link is meant to give a comprehensive list of accepted extensions/types, but Graphics.GetGraphicClassForFileExtension can give a class that supports a specific extension if available. And passing TGraphic to Graphics.GraphicFilter will provide a list of file extensions, on my system at this time I get:
Quote
*.png;*.xpm;*.bmp;*.cur;*.ico;*.icns;*.jpeg;*.jpg;*.jpe;*.jfif;*.tif;*.tiff;*.gif;*.pbm;*.pgm;*.ppm

With a few lines of code:
Code: [Select]
var
  GC, oldGC: TGraphicClass;
  sl: TStringList;
  AllFilters: String;
  aFilter, aExt: String;
begin
  AllFilters := GraphicFileMask(TGraphic);
  Memo1.Lines.Add(AllFilters);

  sl := TStringList.Create;
  try
    sl.Delimiter := ';';
    sl.DelimitedText := AllFilters;
    for aFilter in sl do
    begin
      aExt := copy(aFilter, 3, Length(aFilter));
      GC := GetGraphicClassForFileExtension(aExt);
      if oldGC <> GC then
      begin
        Memo1.Lines.Add(GraphicFilter(GC));
        oldGC := GC;
      end;
    end;
  finally
    sl.Free;
  end;
end;

it could be turned to:
Quote
Portable Network Graphic (*.png)|*.png
Pixmap (*.xpm)|*.xpm
Bitmaps (*.bmp)|*.bmp
Cursor (*.cur)|*.cur
Icon (*.ico)|*.ico
Mac OS X Icon (*.icns)|*.icns
Joint Picture Expert Group (*.jpeg;*.jpg;*.jpe;*.jfif)|*.jpeg;*.jpg;*.jpe;*.jfif
Tagged Image File Format (*.tif;*.tiff)|*.tif;*.tiff
Graphics Interchange Format (*.gif)|*.gif
Portable PixMap (*.pbm;*.pgm;*.ppm)|*.pbm;*.pgm;*.ppm

More over the log of the source code (http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/lcl/include/picture.inc?root=lazarus&r1=26449&r2=26758) shows that Image1.Picture.LoadFromFile can handle *.gif for over four years now, thanks to a patch (http://bugs.freepascal.org/view.php?id=0016993) by José Mejuto.
Title: Re: Changing pictures after reaching value on the TImage component
Post by: mm7 on March 13, 2015, 07:25:25 pm
Neither link is meant to give a comprehensive list of accepted extensions/types, but Graphics.GetGraphicClassForFileExtension can give a class ...
Thank you for the example. I see that lots of formats are actually supported.
And if this support has been added time ago, and well tested, then why not to update the documentation?

What I am trying to say, in most of mature systems there also some features appear before they get documented. But they are treated as "undocumented features", that are not recommended for use, especially for production use, until they are released and documented.
From what you are saying I see that this approach does not apply to FPC/Lazarus. Then how to be sure that some new cool feature I use today, will not change tomorrow, and something will stop compile or work?
Title: Re: Changing pictures after reaching value on the TImage component
Post by: mm7 on March 13, 2015, 07:30:54 pm
Next thing I'd like to achieve is to make proper counters which will show separately how many seats are free (counting green images of seats) or not (red image of seat).
gromar, it is not clear what are you trying to achieve?
An image of a bus with seats, each painted red/green depending on their booking status? or something else?
Title: Re: Changing pictures after reaching value on the TImage component
Post by: engkin on March 13, 2015, 07:56:10 pm
Neither link is meant to give a comprehensive list of accepted extensions/types, but Graphics.GetGraphicClassForFileExtension can give a class ...
Thank you for the example. I see that lots of formats are actually supported.
And if this support has been added time ago, and well tested, then why not to update the documentation?

I believe the question is "who will update the documentation?". Remember it's open source project and the answer is simple: the community (read you, me and others). If enough people volunteer then we will have enough people to update the documentation. Take a look at the bugtracker (http://bugs.freepascal.org/view_all_bug_page.php?project_id=1), for instance.

From what you are saying I see that this approach does not apply to FPC/Lazarus. Then how to be sure that some new cool feature I use today, will not change tomorrow, and something will stop compile or work?

Usually a better method gets introduced before removing the older one, and the trend is to try not to break older working code. When changes are needed then they are mentioned in rge wiki like User Changes (http://wiki.lazarus.freepascal.org/Category:FPC_User_Changes_by_release).

What I mentioned here is just my own opinion and observation.
Title: Re: Changing pictures after reaching value on the TImage component
Post by: mm7 on March 13, 2015, 08:19:27 pm
I believe the question is "who will update the documentation?".
I understand that it is community based product. My question was rather regarding a "philosophy" of it - what to believe - the code or the docs? I see that the answer is - Believe the code. Docs are secondary.
Fair enough.

Usually a better method gets introduced before removing the older one, and the trend is to try not to break older working code. When changes are needed then they are mentioned in rge wiki like User Changes (http://wiki.lazarus.freepascal.org/Category:FPC_User_Changes_by_release).
Thanks! I'll try to remember.
Title: Re: Changing pictures after reaching value on the TImage component
Post by: gromar on March 16, 2015, 09:54:06 am
Next thing I'd like to achieve is to make proper counters which will show separately how many seats are free (counting green images of seats) or not (red image of seat).
gromar, it is not clear what are you trying to achieve?
An image of a bus with seats, each painted red/green depending on their booking status? or something else?
Hello,

exactly that's the thing I'd like to achieve. My visualization shows booking status of seats in the bus. You can see whole bus with seats which should change colours and also numbers of free/ busy seats below the main picture. For example: at first there are 42 free green seats so we can see text: "42 free"; "0 busy". Let's say 2 people will sit on two seats. Main pic will change: there will be 40 seats green and 2 red one. Same with the text below: "40 free" and "2 busy".
Title: Re: Changing pictures after reaching value on the TImage component
Post by: taazz on March 17, 2015, 06:24:46 am
here take this sample and add the rest of the seats and the editors.
http://sourceforge.net/projects/codelibrarian/files/Pre_Release/various/BusSeats.zip/download (http://sourceforge.net/projects/codelibrarian/files/Pre_Release/various/BusSeats.zip/download)
Title: Re: Changing pictures after reaching value on the TImage component
Post by: gromar on May 06, 2015, 01:23:10 pm
Thank you for the code - it helped me a lot with my project. Still I have some questions how to finialize it:

- I can't get the exactly number of seats which are free /busy on visualization ( I would like to see counter which will show how many seats are free and another counter which will show how many seats are busy );
- this part can be tricky - I'm also trying to synchronize signals from bananaPi computer with the visualization. Example: each sensor (which is hidden in each seat) is wired with one module box which is next connected with BananaPi and on this computer user has got the visualization which we are trying write here. All is connected via CAN bus. Using CAN bus with sensors allow you to set separate adress to each seat with sensors. The main goal I'd like to achieve is to pair visualization with those sensors using CAN bus. Has anyone tried earlier to read signals from BananaPI (RX, TX and CANL, CANH) and then make them visualized on screen using Delphi language. I tried to get information on BananaPi forums but unfortunately with no luck :(

In link below I send my actual version of my project.
http://speedy.sh/2fxCC/bus-seats201505061219.tar

Thanks in advance for any information.
Title: Re: Changing pictures after reaching value on the TImage component
Post by: User137 on May 07, 2015, 04:14:15 am
You have the data in some kind of arrays? It should be simple task to go through them in a for-loop.

Do not try to read information from visualization, read it from the data itself. Because visualization is also drawn based of the data.
Title: Re: Changing pictures after reaching value on the TImage component
Post by: gromar on May 11, 2015, 02:06:05 pm
Hi again!

I managed to synchronize signals from module box (CAN bus line) to BananaPi using TI SN65HVD230D transceiver. I got information from each ID seat section per one frame (seats 1-32 , 33-64 and status of each seat - free, taken, error and not available). I attach image example of frames I get using ./receive command with can4linux and table content of all ID frames. I wonder how I can next visualize all the process in Delphi. How should I attribute exact frame (from RX/TX signals of BananaPI gpio)  to a correct color and number of seat graphic icon. Thank you in advance for each tip :)

Example:

0.167986     938/0x000003aa : bD  ( 8 ): 00 fc ff ff ff ff ff 3f - noone is sitting
0.167963     938/0x000003aa : bD  ( 8 ): 01 fc ff ff ff ff ff 3f - seat no 1 is taken/ busy
0.167972     938/0x000003aa : bD  ( 8 ): 04 fc ff ff ff ff ff 3f - seat no 2 is taken/ busy
0.167973     938/0x000003aa : bD  ( 8 ): 10 00 fc ff ff ff ff 3f - seat no 3 is taken/busy
0.167973     938/0x000003aa : bD  ( 8 ): 40 00 fc ff ff ff ff 3f - seat no 4 is taken/busy
0.167981     938/0x000003aa : bD  ( 8 ): 00 01 fc ff ff ff ff 3f - seat no 5 is taken/busy
0.168021     938/0x000003aa : bD  ( 8 ): 00 04 fc ff ff ff ff 3f - seat no 6 is taken/busy
0.167986     938/0x000003aa : bD  ( 8 ): 00 10 fc ff ff ff ff 3f - seat no 7 is taken/busy
0.167988     938/0x000003aa : bD  ( 8 ): 00 40 fc ff ff ff ff 3f - seat no 8 is taken/busy
0.168017     938/0x000003aa : bD  ( 8 ): 00 00 fd ff ff ff ff 3f - seat no 9 is taken/busy

0.168023      938/0x000003aa : bD  ( 8 ): 00 00 fc ff ff ff ff 7f - seat no 32 is taken/busy
0.167001      939/0x000003ab : bD  ( 8 ): ff ff ff ff ff fc ff ff - seat no 53 is free
0.167023      939/0x000003ab : bD  ( 8 ): ff ff ff ff ff fd ff ff - seat no 53 is taken/busy

0.167992      938/0x000003aa : bD  ( 8 ): 00 01 fc ff ff ff ff 7f - seat no 5 & 32 are taken/ busy
0.167986      938/0x000003aa : bD  ( 8 ): 05 00 fc ff ff ff ff 3f - seat no 1 & 2 are taken/ busy
0.167965      938/0x000003aa : bD  ( 8 ): 40 01 fc ff ff ff ff 3f - seat no 4 & 5 are taken/ busy

0.167971      938/0x000003aa : bD  ( 8 ): 50 01 fc ff ff ff ff 3f - seat no 3, 4 and 5 are taken/busy
TinyPortal © 2005-2018