Recent

Author Topic: TAChart AreaBrush patter or image  (Read 4328 times)

immoblecher

  • Newbie
  • Posts: 5
TAChart AreaBrush patter or image
« on: October 13, 2015, 04:07:25 pm »
I created a geological log with TAChart and use TAreaSeries to plot the geological lithologies. In order to show different lithologies I use the AreaBrush.Style, but that one has only 7 patterns (including bsSolid) which can be used, which is not really enough. There is the option of using bsPattern or bsImage, but I am unable to figure out how they could be used, e.g. with predefined bitmap or JPG images, which could be stored in a lookup database and extracted according to the lithology to be plotted. The colour of these patterns or bitmaps also needs to be adapted according to lithology colour as in the description or as stored in the lookup table.

Any other ideas, if TAreaSeries is not really the right series type to use? Any ideas how to use bsPattern or bsImage for this? I am really stuck.  :(

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: TAChart AreaBrush patter or image
« Reply #1 on: October 13, 2015, 04:51:55 pm »
Your version is probably too old (or you are doing something very wrong...), I am counting 10 patterns in the AreaBrush.Style dropdown.

Select bsImage for AreaBrush.Style of the AreaSeries. Then, at run-time, maybe in FormCreate, load the fill pattern bitmap (if it's not a bitmap convert the image to a bmp) and set AreaBrush.Image := bitmap.

In my test this code produces the chart of the attachment:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   bmp: TBitmap;
  4. begin
  5.   bmp := TBitmap.Create;
  6.   bmp.LoadFromFile('09.bmp');
  7.   Chart1AreaSeries1.AreaBrush.Bitmap := bmp;
  8. end;
  9.  
  10. { in case of a jpeg you would replace the bmp.LoadromFile by this:
  11. var
  12.   jpeg: TJpegImage;
  13.   ...
  14.   jpeg := TJpegImage.Create;
  15.   try
  16.     jpeg.LoadFromFile(filename);
  17.     bmp.Assign(jpeg);
  18.   finally
  19.     jpeg.Free;
  20.   end;
  21. }
« Last Edit: October 13, 2015, 05:46:16 pm by wp »

immoblecher

  • Newbie
  • Posts: 5
Re: TAChart AreaBrush patter or image
« Reply #2 on: October 13, 2015, 06:05:30 pm »
Thank you wp, this is what I need. But if I do it exactly as you described I get a "External: SIGSEGV", and that after the Form.Show event, in which I create the charts and series. If I click OK it shows the chart, but the AreaSeries are not there. I have changed nothing else in the code which now is:

Code: Pascal  [Select][+][-]
  1.             AreaBrush.Style := bsImage;
  2.             BitMapSection := TBitmap.Create;
  3.             BitMapSection.LoadFromFile('...\BRIT14.BMP');
  4.             AreaBrush.Bitmap := BitMapSection;
  5.             BitMapSection.Free;
  6.  

Which unit do I need to include to use the style bsImage? FPCanvas?
BTW: I also have 10 AreaBrush.Styles, which include bsClear, which I can't use, and bsImage and bsPattern.

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: TAChart AreaBrush patter or image
« Reply #3 on: October 13, 2015, 06:23:31 pm »
Of course you can apply the image to the AreaSeries only after you have created the series. You say you do this in FormShow, then copy my code to FormShow (AFTER creating the series). BTW, there are situations that FormShow can be called multiple times - this means that you create the chart several times, but access with the same variable name --> memory leak. Why don'y you use FormCreate? - its name say that this is method to "create" things...

immoblecher

  • Newbie
  • Posts: 5
Re: TAChart AreaBrush patter or image
« Reply #4 on: October 14, 2015, 01:18:31 pm »
I have solved the initial problem: the BitMapSection should not be freed, which obviously causes the SIGSEGV.
But now I want to read the bitmaps from a SQLite table from a BLOB field called LOGS_BMP and whatever I try it does not read the bitmaps properly and I get a "Wrong image format" error. They are stored as bitmaps in the table and I use another form to read them into a DBImage (DBImageDBImageRead) and can change them and save them in the database.
I also want to change the colour of the bitmap to be the same colour as the SeriesColour, but my code does not work (with bitmaps loaded from file or the BLOB field). This is the code I use:

Code: Pascal  [Select][+][-]
  1.  
  2.          if DataModuleMain.LookupTableLOGS_BMP.Value <> Null then
  3.          begin
  4.             //set AreaBrush from the LOGS_BMP
  5.             BitMapSection := TBitmap.Create;
  6.             BS := DataModuleMain.LookupTable.CreateBlobStream(DataModuleMain.LookupTable.FieldByName('LOGS_BMP'), bmRead);
  7.             BS.Position := 0;
  8.             BitMapSection.LoadFromStream(BS);
  9.             for w := 0 to BitMapSection.Width - 1 do
  10.             begin
  11.               for h := 0 to BitMapSection.Height - 1 do
  12.                 if BitMapSection.Canvas.Pixels[w, h] <> clWhite then
  13.                   BitMapSection.Canvas.Pixels[w, h] := SeriesColor;
  14.             end;
  15.             AreaBrush.Bitmap := BitMapSection;
  16.             BS.Free;
  17.           end
  18.           else...

What am I doing wrong? If I build in code to save the bitmap from the BLOB field to a file then the file is empty (0 size). I also tried a hidden DBImage on the form to read the BLOB, but saving the resulting bitmap to a file returns an empty file.

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: TAChart AreaBrush patter or image
« Reply #5 on: October 14, 2015, 01:39:12 pm »
My first impression is that your code is correct. Three tests:
(1) if you copy the BlobStream to file after line 7 is the file? (I think you say thay). This indicates that the images are not written to the blob field correctly.
(2) Assuming the blob field is written correctly: If you write the bitmap to a file (after line 8) can you open the file by the image processing tools of your OS? If not the bitmap file is not written correctly
(3) Assuming the bitmap has the correct file format: If you comment out the image modification part (lines 9-14) read from the blobstream can you use the bitmap for the area brush? If yes you seem to see the same issue that I see when modifying image bitmaps and reusing the modified bitmaps in the gui - no solution so far.

immoblecher

  • Newbie
  • Posts: 5
Re: TAChart AreaBrush patter or image
« Reply #6 on: October 14, 2015, 04:32:15 pm »
I know this is absolutely weird! As I said on another form (attached) I provide the user with the functions to edit and change or add the bitmaps to the SQLite Lookup database. The user clicks on the bitmap to the right when in edit mode and chooses the bitmap from disk. The DBImage is updated accordingly and on post the bitmap is saved to the database. When I close and open the form it is there.
Here is the read and write code:

Code: Pascal  [Select][+][-]
  1. procedure TEditLogPatternForm.DBImageDBImageRead(Sender: TObject; S: TStream;
  2.   var GraphExt: string);
  3. var val1, val2:  WORD;
  4. begin
  5.   S.Seek(0, soFromBeginning);
  6.   S.Read(val1, 2);
  7.   S.Position := 2;
  8.   S.Read(val2, 2);
  9.   if (val1 = $4D42) then  GraphExt := 'bmp';
  10.   if (val1 = $4947) and (val2 = $3846) then  GraphExt := 'gif';
  11.   if (val1 = $5089) and (val2 = $474E) then  GraphExt := 'png';
  12.   if (val1 = $D8FF) and (val2 = $E0FF) then  GraphExt := 'jpg';
  13.   S.Seek(0, soFromBeginning);
  14. end;

Code: Pascal  [Select][+][-]
  1. procedure TEditLogPatternForm.DBImageClick(Sender: TObject);
  2. var
  3.   FileStream: TStream;
  4. begin
  5.   if ZTableLookup.State = dsEdit then
  6.   begin
  7.     OpenPictureDialog.InitialDir := ProgramDir + '\Bitmaps';
  8.     if OpenPictureDialog.Execute  then
  9.     begin
  10.       FileStream := TFileStream.Create(OpenPictureDialog.FileName, fmOpenRead);
  11.       try
  12.         ZTableLookupLOGS_BMP.LoadFromStream(FileStream);
  13.       finally
  14.         FileStream.Free;
  15.       end;
  16.     end;
  17.   end
  18.   else
  19.     MessageDlg('Lithology table not in edit state! Make the table editable first.', mtWarning, [mbOK], 0);
  20. end;

Saving the file after line 7? How do I copy a BlobStream to a file? As soon as I do the BitMapSection.LoadFromStream(BS) I get the "Wrong image format" error.
If I debug my code in the DBImageDBImageRead procedure I get the correct GraphExt as 'bmp', so theoretically the bitmaps should be stored correctly.
I am considering just saving the names of the bitmaps in the Blobfield and keep the bitmaps in a subfolder of my application but that would have all sorts of other implications.

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: TAChart AreaBrush patter or image
« Reply #7 on: October 14, 2015, 04:48:29 pm »
Your code tells me that the images stored in the DB can be of any format, right? Then, of course, you cannot load load them into a bitmap in the first place, because a bitmap accepts only bmp files. You determine the file format from reading the header. So, if the header is that of a bmp load the stream into a TBitmap, if it is that of a jpeg load the stream into a TJpegImage etc.

 

TinyPortal © 2005-2018