Lazarus

Programming => Graphics => Graphics and Multimedia => BGRABitmap and LazPaint => Topic started by: circular on March 12, 2011, 02:47:08 pm

Title: BGRABitmap tutorial
Post by: circular on March 12, 2011, 02:47:08 pm
Hello people.

BGRABitmap is a drawing library to draw antialiased and alphablended graphics, gradients, textures etc.
It's beginning to work fine. So I've written some tutorials on Lazarus wiki for BGRABitmap library. It starts here :

http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial

There are also examples in testbgrafunc folder of LazPaint archives :

http://sourceforge.net/projects/lazpaint/files/lazpaint/

Have fun!
 8)
Title: Re: BGRABitmap tutorial
Post by: lainz on March 12, 2011, 03:10:38 pm
Add some pictures :)

Here is an example with BGRABitmap to create 'like flash player setup' single gradient button.

Add a PaintBox and set name to 'btn1', then go to 'On Paint' event and add this code:

Code: [Select]
  var
    tempbmp1, tempbmp2: TBGRABitmap;
  begin
    // Background Gradient
    tempbmp1:=TBGRABitmap.Create(btn1.Width,btn1.Height,BGRA(104,104,104,255));
    tempbmp1.Canvas.GradientFill(Rect(1,Round(btn1.Height*0.25),btn1.Width-1,btn1.Height-1),$686868,$404040,gdVertical);

    // Frame Border
    tempbmp1.Canvas.Brush.Color:=$181818;
    tempbmp1.Canvas.FrameRect(btn1.ClientRect);

    // Light Gradient
    tempbmp2:=TBGRABitmap.Create(btn1.Width,btn1.Height,BGRA(0,0,0,0));
    tempbmp2.GradientFill(1,1,btn1.Width-1,btn1.Height-1,
    BGRA(255,255,255,34),
    BGRA(255,255,255,10), gtLinear,
    PointF(btn1.ClientRect.Right,btn1.ClientRect.Top),
    PointF(btn1.ClientRect.Right,btn1.ClientRect.Bottom),
    dmDrawWithTransparency,True,False);
    tempbmp2.AlphaFillRect(2,2,btn1.Width-2,btn1.Height-2,0);

    // Merge Bitmaps
    tempbmp1.Canvas.Draw(0,0,tempbmp2.Bitmap);

    // Paint in Canvas
    btn1.Canvas.Draw(0,0,tempbmp1.Bitmap);

    // Free Bitmaps
    tempbmp1.Free;
    tempbmp2.Free;
end;
Title: Re: BGRABitmap tutorial
Post by: lainz on March 12, 2011, 07:34:57 pm
Here is another example with BGRABitmap to create 'like windows 7' explorer toolbar.

This requires also Double Gradient ( http://wiki.lazarus.freepascal.org/Double_Gradient )

Add a PaintBox and set name to 'btn2', then go to 'On Paint' event and add this code:

Code: Pascal  [Select][+][-]
  1. var
  2.   backBmp, lightBmp: TBGRABitmap;
  3.   gradBmp: TBitmap;
  4. begin
  5.   // Background Gradient
  6.   gradBmp := DoubleGradientFill(
  7.               btn2.ClientRect,
  8.               $FFFAF5,$FAF0E6,
  9.               $F4E6DC,$F7E9DD,
  10.               gdVertical,gdVertical,gdVertical,0.5);
  11.  
  12.   // Use as background
  13.   backBmp := TBGRABitmap.Create(gradBmp);
  14.   gradBmp.Free;
  15.  
  16.   // Light Gradient
  17.   lightBmp:= TBGRABitmap.Create(btn2.Width,btn2.Height,BGRA(0,0,0,0));
  18.    lightBmp.Rectangle(0,0,btn2.Width,btn2.Height-2,  
  19.      BGRA(255,255,255,100),
  20.      dmSet);  
  21.    lightBmp.SetHorizLine(0,btn2.Height-1,btn2.Width-1,BGRA(160,175,195,255));  
  22.    lightBmp.SetHorizLine(0,btn2.Height-2,btn2.Width-1,BGRA(205,218,234,255));
  23.  
  24.   // Merge Bitmaps
  25.   backBmp.PutImage(0,0,lightBmp,dmDrawWithTransparency);
  26.   lightBmp.Free;
  27.  
  28.   // Paint in Canvas
  29.   backBmp.Draw(btn2.Canvas,0,0,True);
  30.   backBmp.Free;
  31. end;
  32.  
Title: Re: BGRABitmap tutorial
Post by: circular on March 12, 2011, 08:28:08 pm
Add some pictures :)
Yes. It's a good idea.

About that line :
Quote
tempbmp1.Canvas.Draw(0,0,tempbmp2.Bitmap);
It does not work on gtk, because TBitmap cannot be drawn with alpha channel. Instead, use :

Quote
tempbmp2.Draw(tempbmp1.Canvas,0,0,False);

Edit: i've added images to the tutorial
Title: Re: BGRABitmap tutorial
Post by: circular on March 12, 2011, 09:01:13 pm
For the Win7 explorer toolbar button, I recommend you to do it this way:
Code: Pascal  [Select][+][-]
  1. var
  2.   backBmp, lightBmp: TBGRABitmap;
  3.   gradBmp: TBitmap;
  4. begin
  5.   // Background Gradient
  6.   gradBmp := DoubleGradientFill(
  7.               btn2.ClientRect,
  8.               $FFFAF5,$FAF0E6,
  9.               $F4E6DC,$F7E9DD,
  10.               gdVertical,gdVertical,gdVertical,0.5);
  11.  
  12.   // Use as background
  13.   backBmp := TBGRABitmap.Create(gradBmp);
  14.   gradBmp.Free;
  15.  
  16.   // Light Gradient
  17.   lightBmp:= TBGRABitmap.Create(btn2.Width,btn2.Height);
  18.   lightBmp.Rectangle(0,0,btn2.Width,btn2.Height-2,
  19.     BGRA(255,255,255,100),
  20.     BGRA(255,255,255,0),
  21.     dmDrawWithTransparency);
  22.   lightBmp.DrawLine(0,btn2.Height-1,btn2.Width,btn2.Height-1,BGRA(160,175,195,255),True);
  23.   lightBmp.DrawLine(0,btn2.Height-2,btn2.Width,btn2.Height-2,BGRA(205,218,234,255),True);
  24.  
  25.   // Merge Bitmaps
  26.   backBmp.PutImage(0,0,lightBmp,dmDrawWithTransparency);
  27.   lightBmp.Free;
  28.  
  29.   // Paint in Canvas
  30.   backBmp.Draw(btn2.Canvas,0,0,True);
  31.   backBmp.Free;
  32. end;
Title: Re: BGRABitmap tutorial
Post by: lainz on March 12, 2011, 09:57:35 pm
Thankyou, I been updated two codes.

But your Win7 explorer toolbar button 'light gradient' doesn't have transparency.
Title: Re: BGRABitmap tutorial
Post by: circular on March 13, 2011, 02:12:21 am
What do you mean?
Title: Re: BGRABitmap tutorial
Post by: lainz on March 13, 2011, 04:01:26 am
What do you mean?

See the attached picture, the 'light gradient' must be alpha 100, but is 100% white, no transparency.
Title: Re: BGRABitmap tutorial
Post by: circular on March 13, 2011, 11:28:46 am
Ok. There was a problem when importing TBitmap. By default, a TBitmap is completely transparent because alpha = 0. I've fixed it on subversion.

By the way, you can simplify the drawing this way :
Code: Pascal  [Select][+][-]
  1.    lightBmp.Rectangle(0,0,btn2.Width,btn2.Height-2,  
  2.      BGRA(255,255,255,100),
  3.      dmSet);  
  4.    lightBmp.SetHorizLine(0,btn2.Height-1,btn2.Width-1,BGRA(160,175,195,255));  
  5.    lightBmp.SetHorizLine(0,btn2.Height-2,btn2.Width-1,BGRA(205,218,234,255));
Title: Re: BGRABitmap tutorial
Post by: circular on March 19, 2011, 11:53:56 pm
I've added a tutorial for layers :
http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_5
Title: Re: BGRABitmap tutorial
Post by: Dibo on March 20, 2011, 12:08:41 am
I am impressed what BGRABitmap can do. It has potential. We could create interesting components (like gradient panels, etc) with design mode. I am now creating descendant of components which have no alpha support on GTK. TBGRAImageList done, now I am working on TBGRASpeedButton.
Title: Re: BGRABitmap tutorial
Post by: circular on March 20, 2011, 11:01:39 pm
Now i've added phong shading (on subversion). You could do pretty buttons with it.  ;)
Title: Re: BGRABitmap tutorial
Post by: Imants on March 21, 2011, 03:13:34 pm
I notice that there is memory leak in

TBGRADefaultBitmap.Init
Begin
...

FFont     := TFont.Create; //<<here
FontName  := 'Arial';
....

When I compiled with Heaptrc it showed this line. An after quick check I didn't find any line where he is destroyed
Title: Re: BGRABitmap tutorial
Post by: circular on March 21, 2011, 04:36:10 pm
You're right. I've taken your remark into account.
Title: Re: BGRABitmap tutorial
Post by: circular on March 22, 2011, 01:31:55 am
I noticed that there is a start of Canvas drawing in FreePascal in unit FPImgCanv. In my distribution, theses Canvas functions are aliased and far from being finished, but anyway, I've added support for it in BGRABitmap. To use it, just write Bitmap.CanvasFP :
Code: Pascal  [Select][+][-]
  1. var bmp: TBGRABitmap;
  2. begin
  3.    ...
  4.    bmp.CanvasFP.Rectangle(20,20,500,500);
  5. end;

Thus, the connection with FreePascal is complete. If it's still not finished, I suppose some functions of BGRABitmap could be easily translated to FPCanvas.
Title: Re: BGRABitmap tutorial
Post by: circular on March 25, 2011, 01:17:52 pm
Hey people.

I've added pen style, line caps and join style. This mean you can now draw a dashed line.

Here is a new tutorial about this :
http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_6
Title: Re: BGRABitmap tutorial
Post by: Ask on March 25, 2011, 01:23:35 pm
Hm, I see your API is totally incompatible with standard TCanvas, TPen, etc --
is this intentional?
For example, if you would implement image.Pen.JoinStyle instead of image.JoinStyle,
this last tutorial would not be even needed.
Title: Re: BGRABitmap tutorial
Post by: circular on March 25, 2011, 03:59:07 pm
It's partially intentional only. The Canvas structure is too limitative for me. The simple fact that there is an alpha channel makes it different. And I do not like the idea of setting pen style and brush style all the time to bsClear or bsSolid etc. that's why I have put functions called Fill or Draw that take the color as a parameter and not as a global variable. I find my syntax lighter than the standard canvas. On the other hand, at the begginning, there was very few drawing functions, so it was not appropriate to make a Canvas object.

It would be possible to add a BGRACanvas object. This must be well thought, because there are different possible choices for parent classes. For example, imagine you have a function that takes a TCanvas object is parameter. It would be weird to derive TBGRACanvas from TCanvas, and there would be no opacity unless using tricks like adding opacity inside Pen and Brush objects, which is not so simple.

So it would be more acceptable to derive TBGRACanvas from TFPCustomCanvas. There would be alpha support, but with TFPColor so anyway any existing TCanvas code would not work. It would be possible to add properties that look like standard TCanvas, but it would not be really compatible, as it could not be passed as a parameter as a TCanvas object.

Can you tell me what you need ?
Title: Re: BGRABitmap tutorial
Post by: Sternas Stefanos on March 25, 2011, 09:07:55 pm
Hm, I see your API is totally incompatible with standard TCanvas, TPen, etc --
is this intentional?
For example, if you would implement image.Pen.JoinStyle instead of image.JoinStyle,
this last tutorial would not be even needed.


Sir, I think BGRABitmap is one of the best Lazarus libraries...
give to lazarus many new abilities...
Title: Re: BGRABitmap tutorial
Post by: lainz on March 26, 2011, 03:43:30 am
Hm, I see your API is totally incompatible with standard TCanvas, TPen, etc --
is this intentional?
For example, if you would implement image.Pen.JoinStyle instead of image.JoinStyle,
this last tutorial would not be even needed.


Sir, I think BGRABitmap is one of the best Lazarus libraries...
give to lazarus many new abilities...

Of course. With BGRABitmap I can re-create any windows / mac ui components like skin of buttons, toolbars, and others, and use those images in all platforms to get the same look of the app.
Title: Re: BGRABitmap tutorial
Post by: circular on March 26, 2011, 07:34:38 am
Hello people.

I had forgotten some features in the tutorial. I added :
- rectangles with mixed join styles
- opened lines

It is always here :
http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_6

I understand that it can be confusing that there is no BGRA canvas, but if I do one, I would like to know what people like. For example, for colors, should it use TFPColor or TBGRAPixel or two properties TColor + Opacity:Byte ?

I prefer not create pen and brush objects alone, I think they should be included in a BGRA canvas.
Title: Re: BGRABitmap tutorial
Post by: Ask on March 26, 2011, 11:18:47 am
I have started work on BGRA back-end for TChart.
So far, I have met the following stumbling blocks:

1) The package does not compile with fpc 2.4.2 due to circular dependencies
(in particular, BGRADefaultBitmap <->BGRAPolygon).
Although this is formally a FPC bug, circular unit dependencies are bad
programming practice, so it would be nice if BGRABitmap avoided it.
I was able to work around it by not using a package and adding
the BGRABitmap source to the unit path -- but I can not publish such a hack
into Lazarus repository.

2) As I suspected in the previous post, porting TCanvas-using code to BGRA
is cumbersome. Some functions, like Ellipse, receive arbitrarily different parameters --
no big deal, of course, but irritating.

3) FPColorToBGRA function is missing. I think it should be extracted from
TBGRADefaultBitmap.SetInternalColor.

4) Some functionality is absent (or maybe I just did not find it):
Font.Orientation, Clipping/ClipRect, Brush.Style, RadialPie.

BTW, I noticed that your tutorials utilize old-style .lrs resources --
I think they should be converted to FPC resources so as not to teach
outdated practices to novice users.

Title: Re: BGRABitmap tutorial
Post by: circular on March 26, 2011, 03:17:40 pm
Do you notice that you are very negative. For example, you say it's totally incompatible. Well, incompatible would not be enough ?

You even say that I'm making your life hard on purpose ! I'm not interested in making your life harder, and I'm not interested in you making my life harder.

As I told you, tell me what you need we'll see what we can do. Try to be positive. I am not your ennemy.

1) The package does not compile with fpc 2.4.2 due to circular dependencies
(in particular, BGRADefaultBitmap <->BGRAPolygon).
Although this is formally a FPC bug, circular unit dependencies are bad
programming practice, so it would be nice if BGRABitmap avoided it.
I was able to work around it by not using a package and adding
the BGRABitmap source to the unit path -- but I can not publish such a hack
into Lazarus repository.
It's not a circular dependency. Units are fully defined in the interface. That's even why there is an interface section, to allow units to use each other without circular dependency.

Now, I'll show you how to say this in positive terms. You would like to use BGRABitmap as a package, but it does not compile, because semi-circular dependencies in packages are not handled by FPC.

This is an information that explains why there are strange messages saying that unit is not used. Of course I thought about circular dependencies, and no the source code is correct. So now what to do ? Waits for a new version of FPC that handles this, reorganise BRGABitmap or use static linking ?

Now we see that we have choices.

Quote
2) As I suspected in the previous post, porting TCanvas-using code to BGRA
is cumbersome. Some functions, like Ellipse, receive arbitrarily different parameters --
no big deal, of course, but irritating.
How can you know that it's arbitrary ? I already tried to explain to you why BGRABitmap is different from standard Canvas. You did not answer at all, and continue in your idea that it's non sense.

Here is the positive formulation. You do not understand why Ellipse receives different parameters from Canvas. You are used to standard canvas functions so you are troubled. Maybe you would want to copy and paste your previous code. I do not know what you need because you do not tell clearly what you need. I need to know what you need to see if I can do something about it. If you don't tell me, you are on your own, and that's your choice.

I told you that it would be possible to do a BGRACanvas. For example, you could create yourself a TBGRACanvas object that calls TBGRABitmap functions, use it and share it with others.

Quote
3) FPColorToBGRA function is missing. I think it should be extracted from
TBGRADefaultBitmap.SetInternalColor.
Positive formulation : you need some FPColorToBGRA function. Well, why not write it yourself, and put it here. Then I would just have to copy and paste it into subversion.

Quote
4) Some functionality is absent (or maybe I just did not find it):
Font.Orientation, Clipping/ClipRect, Brush.Style, RadialPie.
That's right, these functions are not implemented. As I thought you would need dashed lines, I programmed it. This was to a certain extent for you.

Quote
BTW, I noticed that your tutorials utilize old-style .lrs resources --
I think they should be converted to FPC resources so as not to teach
outdated practices to novice users.
It's rather a secondary aspect if it works. That's the version of Lazarus that I'm using and that is available on Ubuntu. I prefer that BGRABitmap be available for users of old version of Lazarus too.
Title: Re: BGRABitmap tutorial
Post by: picstart on March 26, 2011, 04:33:58 pm
I'm having issues with the tutorial
Downloaded the latest code 2.6 from svn then set the path in project compiler options and added  BGRABitmap, BGRABitmapTypes to the uses

For tutorial 6
Code: [Select]
procedure TForm1.FormPaint(Sender: TObject);
var image: TBGRABitmap;
    c: TBGRAPixel;
begin
  image := TBGRABitmap.Create(ClientWidth,ClientHeight,ColorToBGRA(ColorToRGB(clBtnFace)));
  c := ColorToBGRA(ColorToRGB(clWindowText));
 
  image.RectangleAntialias(80,80,300,200,c,50);
 
  image.Draw(Canvas,0,0,True);
  image.free;
end;
the example shows chiseled corners but I get square
Next it says add image.JoinStyle := pjsRound;
and get rounded corners image doesn't have JoinStyle
Many of the other features like
FillRoundRectAntialias are missing from Tgrabbitmap
laz 9.30 fpc 2.4.2 win32XP
Title: Re: BGRABitmap tutorial
Post by: Ask on March 26, 2011, 04:45:28 pm
Quote
Do you notice that you are very negative.
I apologize if I offended you, of course I think BGRA has much potential --
this is why I am trying to utilize it.
In fact, I had an idea of proposing BGRA for inclusion in Lazarus --
and I think in this case the problems I mentioned would probably worry other
Lazarus developers as well.
Please believe me that my comments are by no means directed at you personally --
only at technical aspects of your library.
I am accustomed to formulating my technical thoughts directly,
but I will certainly try to say things in your preferred way in the future.

Quote
For example, you say it's totally incompatible.
Well, incompatible would not be enough ?
Again, sorry -- but yes, I did mean "totally" incompatible as opposed to
"slightly" incompatible -- for an example of the latter, see e.g. AggPas implementation.

Quote
That's even why there is an interface section, to allow units to use each other without circular dependency.
You mean implementation section?
Anyway, this is just a difference of terms -- I prefer to say that
implementation section allows to use units *with* circular
(or semi-circular -- nice word for this situation, BTW) dependency,
because dependency does not go away, it is only worked around.

Quote
Wait for a new version of FPC that handles this, reorganise BRGABitmap or use static linking ?

New version of FPC may or may not fix this -- it is a well-known long-standing
hard-to-fix bug. As for static linking -- I am not sure what you mean,
AFAIK, fpc programs are statically linked by default.
So, *I* would like the second choice -- but of course, it is your project, so you decide.

Quote
How can you know that it's arbitrary ? I already tried to explain to you why BGRABitmap is different from standard Canvas.
You did, and I have taken note of what you said.
However, in the case of ellipse I do not see any reason to prefer either "bounding box"
or "center and radii" approach, but the first one is well-established
in all Delphi/FPC graphics library I know, so I was surprised that you decided to take the second one.
Anyway, this is actually very trivial to work around (and I already did), so no need to worry.

Quote
you need some FPColorToBGRA function. Well, why not write it yourself, and put it here. Then I would just have to copy and paste it into subversion.

Ah, sure, here it is:

Code: [Select]
procedure FPColorToBGRA(AValue: TFPColor);
begin
  with AValue do
    Result := BGRA(red shr 8, green shr 8, blue shr 8, alpha shr 8);
end;

I did not post it because:
1) If you decide to implement it, you should also use it instead if inlined code
in TBGRADefaultBitmap.SetInternalColor function
2) This is best expressed with the patch, but I wanted to avoid making post too long,
and the issue is very simple -- so I thought that the phrase "extract from
TBGRADefaultBitmap.SetInternalColor" will be the most direct and compact way to express
my intention. Obviously I failed to make it understandable enough, sorry for that.

Quote
As I thought you would need dashed lines, I programmed it. This was to a certain extent for you.
Thanks, this is very appreciated.
Unfortunately, dashed lines did not work for me on the first try--
but I did not yet investigate deeply, it is quite possible this is due to my mistake.

Quote
I prefer that BGRABitmap be available for users of old version of Lazarus too.
Ah, ok -- I just wanted to let you know.

In conclusion, I do look forward to working with BGRA -- because is seems to finally
bring working transparency implementation, which both FPImage/FPCanvas and LCL failed to
do for a long time. Please continue your good work.
Title: Re: BGRABitmap tutorial
Post by: circular on March 26, 2011, 05:59:00 pm
Quote
Do you notice that you are very negative.
I apologize if I offended you, of course I think BGRA has much potential --
this is why I am trying to utilize it.
In fact, I had an idea of proposing BGRA for inclusion in Lazarus --
and I think in this case the problems I mentioned would probably worry other
Lazarus developers as well.
Please believe me that my comments are by no means directed at you personally --
only at technical aspects of your library.
I am accustomed to formulating my technical thoughts directly,
but I will certainly try to say things in your preferred way in the future.
Ok, thanks.

Quote
Quote
For example, you say it's totally incompatible.
Well, incompatible would not be enough ?
Again, sorry -- but yes, I did mean "totally" incompatible as opposed to
"slightly" incompatible -- for an example of the latter, see e.g. AggPas implementation.
Ok, this needs to be developped to be correctly understood.

Quote
Anyway, this is just a difference of terms -- I prefer to say that
implementation section allows to use units *with* circular
(or semi-circular -- nice word for this situation, BTW) dependency,
because dependency does not go away, it is only worked around.
In a certain way, yes, but it's not a problem. It's a mutual dependence. It's like in life, we are all mutually dependent.

Quote
New version of FPC may or may not fix this -- it is a well-known long-standing
hard-to-fix bug. As for static linking -- I am not sure what you mean,
AFAIK, fpc programs are statically linked by default.
I meant included as units, not as a package.

Quote
So, *I* would like the second choice -- but of course, it is your project, so you decide.
I understand. I am also favorable to this if the FPC bug cannot be fixed. It's hard for me to believe it cannot be fixed, but anyway, it's likely to take some time.

What changes do you suggest to avoid mutual references ?

Quote
How can you know that it's arbitrary ? I already tried to explain to you why BGRABitmap is different from standard Canvas.
You did, and I have taken note of what you said.
However, in the case of ellipse I do not see any reason to prefer either "bounding box"
or "center and radii" approach, but the first one is well-established
in all Delphi/FPC graphics library I know, so I was surprised that you decided to take the second one.
Anyway, this is actually very trivial to work around (and I already did), so no need to worry.

Quote
Code: [Select]
procedure FPColorToBGRA(AValue: TFPColor);
begin
  with AValue do
    Result := BGRA(red shr 8, green shr 8, blue shr 8, alpha shr 8);
end;
Ok. I've copied it (i've changed procedure to function).

Quote
1) If you decide to implement it, you should also use it instead if inlined code
in TBGRADefaultBitmap.SetInternalColor function
Ok.

Quote
2) This is best expressed with the patch, but I wanted to avoid making post too long,
and the issue is very simple -- so I thought that the phrase "extract from
TBGRADefaultBitmap.SetInternalColor" will be the most direct and compact way to express
my intention. Obviously I failed to make it understandable enough, sorry for that.
Ok, I'm not familiar with extracting functions, but now I see what you mean.

Quote
Unfortunately, dashed lines did not work for me on the first try--
but I did not yet investigate deeply, it is quite possible this is due to my mistake.
What happens?

Quote
In conclusion, I do look forward to working with BGRA -- because is seems to finally
bring working transparency implementation, which both FPImage/FPCanvas and LCL failed to
do for a long time. Please continue your good work.
Thanks. By the way, I still think that a canvas would be a good idea. But I would like first to determine the needs, what is the best option for everyone.

The options are still :
- using TFPColor
- using TColor and a byte for Opacity
- using TBGRAPixel
- combining them
Title: Re: BGRABitmap tutorial
Post by: lainz on March 26, 2011, 06:05:16 pm
The options are still :
- using TFPColor
- using TColor and a byte for Opacity
- using TBGRAPixel
- combining them

I like TBGRAPixel, but converting TPFColor to BGRAPixel with 'byte for Opacity' and vice-versa if posible to use with the color property of all the current lazarus components..
Title: Re: BGRABitmap tutorial
Post by: circular on March 26, 2011, 08:11:37 pm
You mean TColor and byte for opacity, along with TBGRAPixel ?
TFPColor is a record with word values (16 bit for each channel).
Title: Re: BGRABitmap tutorial
Post by: lainz on March 26, 2011, 11:50:17 pm
You mean TColor and byte for opacity, along with TBGRAPixel ?

Sorry I forget the 'BGRAToColor' and 'ColorToBGRA'. BGRAPixel is ok for me.

You know who is better to use with LCL? - if possible - to give LCL the ability to use alpha...?

TFPColor is a record with word values (16 bit for each channel).

Ok. I must say 'TColor'.
Title: Re: BGRABitmap tutorial
Post by: Ask on March 27, 2011, 09:36:25 am
Quote
I meant included as units, not as a package.
I see. Unfortunately, this is limits usage possibilities -- for example,
while I have already created a demo of TChart drawn on TBGRABitmap,
I can not publish it, since it does not use package and so
includes a unit path to a specific location on my local hard disk.

Quote
It's hard for me to believe it cannot be fixed,
You might want to read some fpc-devel threads on the topic --
then you will see what real negative posts look like :)

Quote
What changes do you suggest to avoid mutual references ?
That's easy -- see attached patch.
Obviously, it may be improved -- for example, you might want to add (and then use)
refcounting for the interface, add the rest if methods to it,
put it in a separate unit intead of TBGRABitmapTypes etc.
I just did a minimal patch for easier review.

Quote
Quote
...dashed lines did not work...
What happens?

Nothing -- lines always are drawn solid.
Looking at the line drawing code, I do not see any references to the PenStyle --
maybe you forgot to implement it?

BTW, you might want to use include files to reduce the code duplication between
line drawing procedures without loss of speed.

Quote
The options are still :
- using TFPColor
- using TColor and a byte for Opacity
- using TBGRAPixel
- combining them

This is indeed a serious problem -- I think that the decision of FPC developers
not to implement TColor was a mistake. I did not yet give up a hope of
convincing them to fix it.
Meanwhile, I think some support of TColor is a must -- there is just
too much code using it.
I suggest the following plan:
1) Internally, use whatever works fastest -- I guess it is TBGRAPixel
2) Provide a functions for conversions with TFPColor/TColor/TColor+Opacity in both directions
(this is already almost done)
3) Provide pen/brush interface -- I believe it is far too entrenched to break now,
and besides, it is not really so bad.
4) (in the future, this is not quite simple)
Put TColor-related functions in a separate unit, and
remove dependencies on Graphics unit in all other code. This will allow
to use BGRABitmap without LCL widgetset -- for example, in web applications.
5) Provide TCanvas emulation and discuss with Lazarus developers the standard interface
for opacity in TFPCanvas/TCanvas.
Title: Re: BGRABitmap tutorial
Post by: Ask on March 27, 2011, 12:00:46 pm
Quote
Ok. I've copied it (i've changed procedure to function).

I do not see it. In which unit did you put it?

Quote
Looking at the line drawing code, I do not see any references to the PenStyle --
maybe you forgot to implement it?

Found it -- you implemented PenStyle for some, but not all line drawing routines.
Changed my code to call supported ones -- still, maybe you want to document this
limitation, as I think it might confuse novice users of BGRABitmap.

Also, my patch in the previous post was against non-tip revision of BGRABitmap.
See attached rebased patch.

Title: Re: BGRABitmap tutorial
Post by: circular on March 27, 2011, 12:08:37 pm
You might want to read some fpc-devel threads on the topic --
then you will see what real negative posts look like :)
It's sad if they are negative with each others. I did not mean that I cannot accept a negative report. I suppose that you understand what I mean.

Quote
That's easy -- see attached patch.
Obviously, it may be improved -- for example, you might want to add (and then use)
refcounting for the interface, add the rest if methods to it,
put it in a separate unit intead of TBGRABitmapTypes etc.
I just did a minimal patch for easier review.
I will look at that.

Quote
Quote
Quote
...dashed lines did not work...
What happens?
Nothing -- lines always are drawn solid.
Looking at the line drawing code, I do not see any references to the PenStyle --
maybe you forgot to implement it?
There are many procedures. Some of these do not take a width w as parameter, and do not implement pen styles.

Quote
BTW, you might want to use include files to reduce the code duplication between
line drawing procedures without loss of speed.
Why not. What do you suggest exactly ?

Quote
This is indeed a serious problem -- I think that the decision of FPC developers
not to implement TColor was a mistake. I did not yet give up a hope of
convincing them to fix it.
You mean that TFPCustomCanvas should include TColor ?

Quote
Meanwhile, I think some support of TColor is a must -- there is just
too much code using it.
I suggest the following plan:
1) Internally, use whatever works fastest -- I guess it is TBGRAPixel
2) Provide a functions for conversions with TFPColor/TColor/TColor+Opacity in both directions
(this is already almost done)
That's right, it's already the case.

Quote
3) Provide pen/brush interface -- I believe it is far too entrenched to break now,
and besides, it is not really so bad.
5) Provide TCanvas emulation and discuss with Lazarus developers the standard interface
for opacity in TFPCanvas/TCanvas.
Where can we contact them on this issue ?

If we make TBGRACanvas to be like TCanvas, it seems to me that the simplest way is to add an Opacity property as a byte. If we use TBGRAPixel internally, then we could have three properties :
- Color: TColor
- Opacity: Byte
- ColorBGRA: TBGRAPixel

Then to set FPColor, it would be like :
- ColorBGRA := BGRA(SomeFPColor);
or
- ColorBGRA := FPColorToBGRA(SomeFPColor);

Or we could add a fourth property to pen and brush
- ColorFP: TFPColor

You did not say anything about class compatibilities, so I suppose you agree that we cannot derive such canvas from TCanvas. By the way, I realised that anyway, TBGRACanvas cannot be fully compatible, because coordinates are floating numbers, unless we add each function twice (one version of integers and one version for single).

Quote
4) (in the future, this is not quite simple)
Put TColor-related functions in a separate unit, and
remove dependencies on Graphics unit in all other code. This will allow
to use BGRABitmap without LCL widgetset -- for example, in web applications.
Why not.
Title: Re: BGRABitmap tutorial
Post by: circular on March 27, 2011, 12:33:29 pm
Ok, i've applied your patch. It works.

Now if I apply it to BGRAResample for example, I need to change many references to TBGRADefaultBitmap. In fact, TBGRADefaultBitmap was also a sort of interface. It would be also possible to create an abstract class, but the problem would be the same, changing all references to TBGRADefaultBitmap to some TBGRAGenericBitmap.

I suppose the interface is a better solution, because it avoids creating virtual functions and includes automatic reference counting. Thank you for this idea.

Is it possible to link actual reference counting functions to interface reference counting functions ?
Title: Re: BGRABitmap tutorial
Post by: Ask on March 27, 2011, 12:38:45 pm
Quote
There are many procedures. Some of these do not take a width w as parameter, and do not implement pen styles.

Hm, it seems what it is actually the reverse -- those procedures that take width as parameter,
do implement PenStyle, others do not.

Quote
You mean that TFPCustomCanvas should include TColor ?
Yes. Even if it will not support "system" colors.

Quote
Where can we contact them on this issue ?
On the mailing list -- see this thread http://www.mail-archive.com/lazarus@lists.lazarus.freepascal.org/msg18414.html (http://www.mail-archive.com/lazarus@lists.lazarus.freepascal.org/msg18414.html) for a recent discussion
of TCanvas/TFPCanvas in relation to TAChart and widgetset-less drawing.

Quote
we could have three properties :
- Color: TColor
- Opacity: Byte
- ColorBGRA: TBGRAPixel

good.

Quote
Or we could add a fourth property to pen and brush
- ColorFP: TFPColor

No need -- TFPCustomPen/TFPCustomBrush (and so, all descendants) already have
FPColor property, which is automatically synchronized with Color in TPen/TBrush.
I think TBGRAPen/TBGRABrush should automatically synchronize all
FPColor/Color+Opacity/BGRAPixel properties.

Quote
I suppose you agree that we cannot derive such canvas from TCanvas
Of course -- that would defeat idea of widgetset independence.
Currently, this means that you will have to write much duplicate/trivial "glue" code.
However, I hope that either TFPCustomCanvas will be extended or
Lazarus will create TCustomCanvas to reduce the interface gap.
I have already some promises from one FPC developer in the thread cited above.

Quote
TBGRACanvas cannot be fully compatible, because coordinates are floating numbers, unless we add each function twice
You do not need to add every function twice -- only those that are present in
TCanvas, and they are quite few compared to what you have in BGRABitmap.
Also, I have noticed that you already overloaded some functions
to receive integers -- so I assume you have a need for this besides TCanvas compatibility.
Title: Re: BGRABitmap tutorial
Post by: Ask on March 27, 2011, 12:48:27 pm
Quote
Is it possible to link actual reference counting functions to interface reference counting functions ?

You mean you want to implement _AddRef/_Release?
Of course it is possible -- the easiest way is to copy them from TInterfacedObject.
Title: Re: BGRABitmap tutorial
Post by: circular on March 30, 2011, 09:49:36 pm
Now BGRABitmap package avoids semi-circular references (updated on subversion and as a zip file).
Title: Re: BGRABitmap tutorial
Post by: circular on March 30, 2011, 10:25:37 pm
Quote
There are many procedures. Some of these do not take a width w as parameter, and do not implement pen styles.

Hm, it seems what it is actually the reverse -- those procedures that take width as parameter,
do implement PenStyle, others do not.
Nope, it was correct.

Quote
Quote
You mean that TFPCustomCanvas should include TColor ?
Yes. Even if it will not support "system" colors.
The problem is maybe that TColor is ambiguous, it can mean plain RGB or a reference to a system color.

Quote
Quote
Where can we contact them on this issue ?
On the mailing list -- see this thread http://www.mail-archive.com/lazarus@lists.lazarus.freepascal.org/msg18414.html (http://www.mail-archive.com/lazarus@lists.lazarus.freepascal.org/msg18414.html) for a recent discussion
of TCanvas/TFPCanvas in relation to TAChart and widgetset-less drawing.
I'm not use to this.

Quote
Also, I have noticed that you already overloaded some functions
to receive integers -- so I assume you have a need for this besides TCanvas compatibility.
Nope, it's just that some line drawing functions use Bresenham algorithm. They are available for convenience only.
Title: Re: BGRABitmap tutorial
Post by: VTwin on March 31, 2011, 04:44:39 pm
This is great circular. I just ran LazPaint 2.6 on OS X 10.6, seems to work well. I tried to open 2.8, but the zip file gave me an error.

Where can I find bgrabitmappack.lpk?

Many thanks for working on this and making it available.

Cheers,
Frederick
Title: Re: BGRABitmap tutorial
Post by: circular on March 31, 2011, 06:50:10 pm
I suppose the upload went wrong. Here I uploaded it again.

Try downloading lazpaint2.8.zip again.
http://sourceforge.net/projects/lazpaint/files/lazpaint/lazpaint2.8.zip/download

You can also use subversion to get version with current modifications. If you have Windows, you need TortoiseSVN for this and then checkout https://lazpaint.svn.sourceforge.net/svnroot/lazpaint.
Title: Re: BGRABitmap tutorial
Post by: gyts on March 31, 2011, 07:22:01 pm
Will there will be more tutorials like this one? I suck on english :/
Title: Re: BGRABitmap tutorial
Post by: circular on March 31, 2011, 09:40:14 pm
You mean tutorials on BGRABitmap or on other Lazarus components or on FreePascal in general ?
Title: Re: BGRABitmap tutorial
Post by: gyts on March 31, 2011, 10:06:55 pm
You mean tutorials on BGRABitmap or on other Lazarus components or on FreePascal in general ?

BGRABitmap.

Edit: For me, any tutorial is useful.
Title: Re: BGRABitmap tutorial
Post by: circular on March 31, 2011, 10:41:54 pm
I could do other tutorials about BGRABitmap. More precisely, what subject interests you ?
Title: Re: BGRABitmap tutorial
Post by: CaptBill on March 31, 2011, 11:49:37 pm
I could do other tutorials about BGRABitmap. More precisely, what subject interests you ?

Hello Circular,
What would be nice is a simple demo like the tutorial (first example w/boxes) which outlines the calling of bezier curves. I tried to implement it like in the demo from the download (ttestdemo I think?) but I keep getting some type of scoping issue w/tpanel when I cut and past to my project. It say's "'got DynArray and requested openarray".

A simple form with a panel set up with a bezier curve predrawn, bare minimum to show the calling and initialization etc. That would be perfect. Maybe a button for each type of curve. Something we can use as a template for us newbies.

Thanks
Title: Re: BGRABitmap tutorial
Post by: VTwin on April 01, 2011, 01:26:19 am
I suppose the upload went wrong. Here I uploaded it again.

Try downloading lazpaint2.8.zip again.
http://sourceforge.net/projects/lazpaint/files/lazpaint/lazpaint2.8.zip/download

You can also use subversion to get version with current modifications. If you have Windows, you need TortoiseSVN for this and then checkout https://lazpaint.svn.sourceforge.net/svnroot/lazpaint.

That seems to have fixed it. I'm primarily on Mac, have not yet delved into using subversion.

Thanks very much circular, I'm trying it out now.
Title: Re: BGRABitmap tutorial
Post by: lainz on April 01, 2011, 01:29:00 am
I could do other tutorials about BGRABitmap. More precisely, what subject interests you ?

I want a tutorial using BGRABitmap with IMGUI or Custom Controls to create own skinned buttons.
Title: Re: BGRABitmap tutorial
Post by: VTwin on April 01, 2011, 02:22:01 am
Circular,

I am curious about available input and output file formats. The LazPaint Save As dialog does not allow picking a file name, so I have not tested the outputs. Can it read the same formats as TPicture? What formats can it write?

Thanks again for your work on this.

Frederick


Edit: I do see all the input formats listed in the LazPaint Open dialog. Is it correct that psd and tiff are not currently implemented? I assume one could open a TPicture though and copy it to a TBGRABitmap?
Title: Re: BGRABitmap tutorial
Post by: gyts on April 01, 2011, 08:04:01 am
How to see all functions and procedures of BGRABitmap?
Title: Re: BGRABitmap tutorial
Post by: circular on April 01, 2011, 11:24:11 am
What would be nice is a simple demo like the tutorial (first example w/boxes) which outlines the calling of bezier curves.
Ok.

Quote
I tried to implement it like in the demo from the download (ttestdemo I think?) but I keep getting some type of scoping issue w/tpanel when I cut and past to my project. It say's "'got DynArray and requested openarray".
I'm surprised. Can you post your code here?
Title: Re: BGRABitmap tutorial
Post by: Ask on April 01, 2011, 12:06:35 pm
Quote
Now BGRABitmap package avoids semi-circular references (updated on subversion and as a zip file).

Yes, it is almost good. Just one reference left -- BGRABitmap <-> BGRAAnimatedGif.
Simply removing BGRAAnimatedGif from BGRABitmap "uses" section fixes the problem,
and then the package works. Thank you.

I am curious as to why did you prefer abstract classes to interfaces in the end?

I have added bgra demo to the TAChart since r30116.
Note that to test it, you have first apply the fix above.
Title: Re: BGRABitmap tutorial
Post by: pch on April 01, 2011, 01:25:02 pm
Hi,
Thank you for the very fine component!

I just have a problem to compile the version 2.8 or the last svn with Gtk2. This is related to TBGRADefaultBitmap/TBGRACustomBitmap.
This seem to work with the attached patch.

About spline, I use them successfully the following way:
var pf: array of TPointF;
...
// fill pf the same way as an array of TPoint for canvas.polybezier
...
BGRAbitmap.DrawPolyLineAntialias(BGRAbitmap.ComputeClosedSpline(pf),ColorToBGRA(color),linewidth,true);

Title: Re: BGRABitmap tutorial
Post by: circular on April 01, 2011, 01:52:25 pm
Yes, it is almost good. Just one reference left -- BGRABitmap <-> BGRAAnimatedGif.
Simply removing BGRAAnimatedGif from BGRABitmap "uses" section fixes the problem,
and then the package works. Thank you.
Ok, it's updated on subversion.

Quote
I am curious as to why did you prefer abstract classes to interfaces in the end?
To keep backward compatibility, so that it's still possible to write "as TBGRABitmap" without warning. On the other side, it's a bit confusing to use an interface without reference counting. And anyway, I needed to have an abstract class for generic creation, so it would have been necessary to have both, and I don't want to have prototypes (in default, in abstract and in interface).

Quote
Note that to test it, you have first apply the fix above.
I'm surprised that it does work for you. Here on win32 version, there was no problem. Anyway it's fixed on subversion.

CaptBill, I added Bézier curves, and completed the tutorial :
http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_7

Bézier functions are available on subversion.
Title: Re: BGRABitmap tutorial
Post by: circular on April 01, 2011, 01:59:25 pm
I just have a problem to compile the version 2.8 or the last svn with Gtk2. This is related to TBGRADefaultBitmap/TBGRACustomBitmap.
This seem to work with the attached patch.
Thanks. I also patched BGRAQtBitmap. I hope it works on Qt too now.
Title: Re: BGRABitmap tutorial
Post by: CaptBill on April 01, 2011, 02:35:10 pm
What would be nice is a simple demo like the tutorial (first example w/boxes) which outlines the calling of bezier curves.
Ok.

Quote
I tried to implement it like in the demo from the download (ttestdemo I think?) but I keep getting some type of scoping issue w/tpanel when I cut and past to my project. It say's "'got DynArray and requested openarray".
I'm surprised. Can you post your code here?

I know it is a scoping issue. If you don't mind taking a look. I know it's something simple I am missing.
Thanks

Quote
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////


unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, Buttons, ComCtrls, ColorBox, Spin, Arrow, Menus, BGRABitmap,
  BGRADefaultbitmap, bgrabitmaptypes, ExtendedNotebook, math, utest;

type
  pointsAr=array of tpoint;
  TArray=array of double;

   TTest = class
  public
    Name: string;
    procedure OnPaint(Canvas: TCanvas; Width,Height: Integer); virtual; abstract;


  end;

     TTest11 = class(TTest)
  protected
    virtualScreen: TBGRABitmap;
    pts: array of TPointF;
    dirs: array of TPointF;
    FFilter: string;
  public



    constructor Create(filter: string);
    destructor Destroy; override;
    procedure OnPaint(Canvas: TCanvas; Width,Height: Integer); override;
    procedure setpoints;
    //procedure setPoints(originX,originY,phiX,phiY,endX,endY:double);
  end;

   { TForm1 }

  TForm1 = class(TForm)
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    CheckBox4: TCheckBox;
    ExtendedNotebook1: TExtendedNotebook;
    Image1: TImage;
    Memo1: TMemo;
    Panel1: TPanel;
    SpeedButton1: TSpeedButton;
    SpeedButton2: TSpeedButton;
    SpeedButton3: TSpeedButton;
    SpeedButton4: TSpeedButton;
    SpeedButton5: TSpeedButton;
    SpinEdit1: TSpinEdit;
    SpinEdit2: TSpinEdit;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    TrackBar1: TTrackBar;
    TrackBar2: TTrackBar;
    TrackBar3: TTrackBar;
    TrackBar4: TTrackBar;
    TrackBar5: TTrackBar;
    TrackBar6: TTrackBar;


    procedure ExtendedNotebook1Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Image1Paint(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure SpeedButton2Click(Sender: TObject);
    procedure SpeedButton3Click(Sender: TObject);
    procedure SpeedButton4Click(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
    procedure TrackBar2Change(Sender: TObject);
    procedure TrackBar5Change(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
  /////////////////////////////////////////////////////////////////////

  function calcPHI2(BaseN:double;count:integer):Tarray;
  function calcPHIdbl(BaseN:double;pos:boolean=true):tarray;
  //function calcXYZsym(BaseN:double;sym:boolean):tArray;
  //function calc_symmetry(BaseN:tarray;shift_positive:boolean):Tarray;
  //function calccompN(BaseN:double);
  procedure memodump1(str:string);
  procedure memodump(ar:tarray);

  procedure redrawArX(ar:tarray);
  procedure redrawArY(ar:tarray);

var
  Form1: TForm1;
  X1pos,Y1pos,Z1pos,X2pos,Y2pos,Z2pos:integer;

implementation
//////////////////////////////////////////////////////////////////
function calcPHI2(BaseN:double;count:integer):Tarray;
var
  ar1,ar2,R_array:tarray;
  i,i2:integer;
  Base_i,maj,min :double ;
begin
{ar1:=nil;
ar2:=nil;
R_array:=nil;}

   base_i:=baseN;
   setlength(ar1,count);
   setlength(ar2,count);
   ar1[0]:=Base_i;
 //  ar2[count]:=0;  //this is wrong
  for i:=0 to count-1 do
    begin

    ar1:=base_i*0.618;
    ar2:=baseN-(base_i-ar1);
    base_i:=ar1;
    //memodump1(floattostr(ar1)+'-----'+floattostr(ar2));
    //memodump1(inttostr(round(ar1)));
    end;

  base_i:=baseN;

  {for i:= 0 to count-1  do
    begin
    ar1:=base_i*0.618;
    ar2:=baseN-(base_i-ar1);
    base_i:=ar1;

   memodump1('---'+inttostr(round(ar2)));
    end;  }
  i2:=(count*2)-1;
  setlength(R_array,(count*2)-1);
  for i:=0 to Count-1 do
    begin
    R_Array:=ar1;
    R_Array[i2]:=ar2;
    i2:=i2-1;
    end;

   result:=R_Array;
 { memodump1('*****');
  memodump(ar1);
  memodump1('*****');
  memodump(ar2);
  memodump1('*****');
  memodump(R_array); }

end;

///////////////////////////////////////////////////
///////////////////////////////////////////////////

function calcPHIdbl(BaseN:double;pos:boolean):tarray;
var
  arA,arB,r_array:tarray;
  i,i2,ic:integer;
  side:boolean=true;
  begin

  arA:=calcPHI2(baseN*0.618,form1.trackbar1.Position);             ///// works fine for first call to calcphi2
  arB:=calcPhi2(BaseN-(basen*0.618),form1.trackbar2.position);     ///// fails here!!   (SIGSEV)
  //memodump(arB);
  //redrawArX(arA);
  //redrawArX(arB);
  ic:=length(arA);
  setlength(r_array,length(arA)+length(arB));

  i2:=length(r_array)-1;
case pos of
 true:
  for i:= 0 to ic-1 do
    begin
    r_array:=basen-(basen*0.618)+arA;
      r_array[i2]:=arB;
      i2:=i2-1;
    end;

  false:
    for i:= 0 to ic-1 do
    begin
    r_array:=arA;
      r_array[i2]:=basen*0.618+arB;
      i2:=i2-1;
    end;
    end;
  //memodump(r_array);
  //redrawArX(r_array);
  result:=r_array;
  end;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
{function calcXYZsym(BaseX,BaseY,BaseZ:double;Xsym,Ysym,Zsym:boolean):tArray;
var
  arX,ar,arY,arZ,r_array:tarray;
  i,i2:integer;
  begin

  arX:= calcPHIdbl(BaseX,true);
  arY:= calcPHIdbl(BaseY,true);
  arZ:= calcPHIdbl(BaseZ,true);
  //calcXYZsym(300,50,30,false,true,false);
  end;  }
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

{function calc_symmetry(BaseN:double;shift_positive:boolean):tarray ;
var
  r_Array,r_ArraySh,bArray:tarray;
  i:integer;

  begin{
  bArray:=calcPHIdbl(BaseN,true);
  for i:= 0 to length(bArray-1) do
  begin
  r_Array:=bArray*(-1)
    end;

case shift_positive of

true:///////////////////
begin
setlength(r_ArraySh,length(r_Array));
  for i:= 0 to length(r_ArraySh-1) do
  r_ArraySh[1]:= r_Array*(-1);
  result:=r_ArraySh;
    end;

false://////////////////
begin
  setlength(r_Array,length(bArray));
  for i:= 0 to length(r_ArraySh-1) do
  r_Array[1]:= r_Array;
  result:=r_Array;
    end;

end; }

end; }

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

procedure memodump(ar:tarray);
var
  i:integer;
begin
//form1.memo1.clear;

For i:= 0 to length(ar)-1 do
  begin

  form1.memo1.Lines.add(floattostr(round(ar)));      ///rounded to integer

  end;
end;

procedure memodump1(str:string);
begin
form1.Memo1.lines.add(str);

end;

{ TForm1 }

procedure Tform1.SpeedButton1Click(Sender: TObject);
var
  a:tarray;
begin
  a:=calcPHI2(300,4);////works fine but only 1 time
  //memodump1('//////////');////2nd try returns 'SIGSEV' error
  //redrawArX(a);

end;

procedure TForm1.Image1Paint(Sender: TObject);
begin

end;

procedure TForm1.ExtendedNotebook1Change(Sender: TObject);
begin

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  X1pos:=1;
  Y1pos:=1;
  Z1pos:=1;
  X2pos:=1;
  Y2pos:=1;
  Z2pos:=1;
end;


procedure TForm1.SpeedButton2Click(Sender: TObject);
var
  a:tarray;
  points:pointsAr;
begin
   // Initial point
  {setlength(ttest11.pts,5);
  ttest11.pts[1].x := 10;

  ttest11.pts[1].y := 10;

  // Final point

  ttest11.pts[4].x := 120;

  ttest11.pts[4].y := 120;

  // Control points

  ttest11.pts[2].x := 10;

  ttest11.pts[2].y := 60;

  ttest11.pts[3].x := 60;

  ttest11.pts[3].y := 10;  }
  ttest11.setpoints;

  Image1.Canvas.PolyBezier(points);
  a:=calcphidbl(300,form1.checkbox1.checked);
  ttest11.onpaint(form1.timage1.canvas, 300,100);
  //redrawArX(a);
end;

procedure TForm1.SpeedButton3Click(Sender: TObject);
var
   bmp: TBGRABitmap;
   p: PBGRAPixel;
   n: integer;

begin
     bmp := TBGRABitmap.Create('image.png');
     p := bmp.Data;
     for n := bmp.NbPixels-1 downto 0 do
     begin
          p^.red := not p^.red;  //invert red canal
          inc(p);
     end;
     bmp.InvalidateBitmap;  //note that we have accessed directly to pixels
     bmp.Draw(Canvas,0,0,True);
     bmp.Free;
end;


procedure TForm1.SpeedButton4Click(Sender: TObject);
var
  bmp: TBGRABitmap;
begin
  //bmp := TBGRABitmap.Create(100,100,BGRABlack); //creates a 100x100 pixels image with black background

  //bmp.FillRect(20,20,60,60,BGRAWhite, dmSet); //draws a white square without transparency
 // bmp.FillRect(40,40,80,80,BGRA(0,0,255,128), dmDrawWithTransparency); //draws a transparent blue square
end;

procedure TForm1.TrackBar1Change(Sender: TObject);
var
  X,Y,Xsym,Ysym:tarray;
begin
  form1.image1.canvas.clear;
  X:=calcphidbl(300,form1.checkbox1.checked);
  Y:=calcphidbl(100,form1.checkbox2.checked);

  //Xsym:=calc_symmetry(X,true);
  //Ysym:=calc_symmetry(Y,true);

  redrawArX(X);
  redrawArY(Y);

  //redrawArX(Xsym);
  //redrawArY(Ysym);
  end;

procedure TForm1.TrackBar2Change(Sender: TObject);
var
  X,Y,Xsym,Ysym:tarray;
begin
  form1.image1.canvas.clear;
  X:=calcphidbl(300,form1.checkbox3.checked);
  Y:=calcphidbl(100,form1.checkbox4.checked);

  //Xsym:=calc_symmetry(X,true);
  //Ysym:=calc_symmetry(Y,true);

  redrawArX(X);
  redrawArY(Y);

end;

procedure TForm1.TrackBar5Change(Sender: TObject);
begin
 // timage.canvas.
end;

procedure redrawArX(ar:tarray);
var
  i:integer;
begin
//form1.image1.canvas.clear;
form1.image1.canvas.pen.Color:=clred;

For i:= 0 to length(ar)-1 do
  begin

  form1.image1.canvas.moveto(round(ar),0);      ///rounded to integer
  form1.image1.canvas.Lineto(round(ar),100);
  end;
end;

procedure redrawArY(ar:tarray);
var
  i:integer;
begin
//form1.image1.canvas.clear;
form1.image1.canvas.pen.Color:=clred;

For i:= 0 to length(ar)-1 do
  begin

  form1.image1.canvas.moveto(0,round(ar));      ///rounded to integer
  form1.image1.canvas.Lineto(300,round(ar));
  end;
end;

constructor TTest11.Create(filter: string);
begin
  inherited Create;
  Name := 'Antialiased lines and splines';
  if filter <> '' then Name += ' with filter '+filter;
  randomize;
  virtualScreen := nil;
  FFilter := filter;
end;

destructor TTest11.Destroy;
begin
  virtualScreen.Free;
  inherited Destroy;
end;

procedure TTest11.OnPaint(Canvas: TCanvas; Width, Height: Integer);
var filtered: TBGRABitmap;
begin
  if pts = nil then exit;

  if (virtualscreen <> nil) and ((virtualscreen.width <> width) or (virtualscreen.Height <> height)) then
  FreeAndNil(virtualScreen);

  if virtualscreen = nil then
    virtualscreen := TBGRABitmap.Create(Width,Height);

  if ffilter = 'Emboss' then
  begin
    virtualScreen.Fill(BGRABlack);
    virtualScreen.DrawPolyLineAntialias(virtualScreen.ComputeOpenedSpline(pts),BGRAWhite,(width+height)/80,True);
    filtered := virtualScreen.FilterEmbossHighlight(True) as TBGRABitmap;
    virtualScreen.Fill(ColorToRGB(clBtnFace));
    virtualScreen.PutImage(0,0,filtered,dmDrawWithTransparency);
    filtered.Free;
    virtualscreen.Draw(Canvas,0,0,True);
  end else
  begin
    virtualScreen.Fill(BGRAWhite);
    virtualScreen.DrawPolyLineAntialias(virtualScreen.ComputeOpenedSpline(pts),BGRA(0,0,0,128),(width+height)/80,True);
    if ffilter = 'Contour' then
    begin
      filtered := virtualScreen.FilterContour as TBGRABitmap;
      filtered.Draw(Canvas,0,0,True);
      filtered.Free;
    end else
    begin
      virtualScreen.DrawPolyLineAntialias(pts,BGRA(0,0,0,128),(width+height)/800,True);
      virtualscreen.Draw(Canvas,0,0,True);
    end;
  end;
end;


  procedure ttest11.setpoints;
  begin
  setlength(pts,3);
    setlength(dirs,3);

    Pts[0].x:= 20;
      Pts[0].y:= 20;
      Pts[1].x:= 200;
      Pts[1].y:= 90;
      Pts[2].x:= 20;
      Pts[2].y:= 200;
      onpaint(form1.timage1.canvas,300,100);

end;

initialization
{$R *.lfm}

end.
       
Title: Re: BGRABitmap tutorial
Post by: circular on April 01, 2011, 04:21:26 pm
It say's "'got DynArray and requested openarray".
On which line?

The problem is about array parameters. I've updated BGRABitmap on subversion to take const arrays as parameters. This should fix this problem. I'll put new zip file soon.
Title: Re: BGRABitmap tutorial
Post by: gyts on April 01, 2011, 07:56:41 pm
Is it possible to do this http://img815.imageshack.us/i/88910461.png/ with BGRABitmap?
Title: Re: BGRABitmap tutorial
Post by: lainz on April 01, 2011, 08:24:27 pm
Is it possible to do this http://img815.imageshack.us/i/88910461.png/ with BGRABitmap?

Yes, see the Lazarus About background:
http://wiki.lazarus.freepascal.org/Sample_Graphics#Lazarus_About

GradientFill with option gtRadial, when you has the bitmap draw in the form.canvas.
Title: Re: BGRABitmap tutorial
Post by: circular on April 02, 2011, 01:25:10 am
Maybe you mean adding some light effect. To do this, create a bitmap with GradientFill gtRadial, then do BlendImage with boMultiply.
Title: Re: BGRABitmap tutorial
Post by: circular on April 02, 2011, 08:30:37 pm
I've added a new tutorial on how create textures with Perlin noise :
http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_8

I will soon add a tutorial for creating textures with Phong shading.
Title: Re: BGRABitmap tutorial
Post by: fabienwang on April 02, 2011, 08:51:03 pm
wow nice! :)
Title: Re: BGRABitmap tutorial
Post by: circular on April 02, 2011, 10:26:49 pm
Thanks  8)

I'm done with the phong texture tutorial :
http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_9

If there is any question, feel free to ask here.
Title: Re: BGRABitmap tutorial
Post by: Gintas on April 03, 2011, 12:25:17 am
I wonder why I can draw image loaded from TStream on another image canvas?
I get error on BGRADefaultBitmap unit 669 line " OldDrawMode := CanvasDrawModeFP; "
Title: Re: BGRABitmap tutorial
Post by: circular on April 03, 2011, 12:28:31 am
Can you post your program so I can see what happens ?
Title: Re: BGRABitmap tutorial
Post by: Gintas on April 03, 2011, 05:21:22 pm
Here ya go!
http://dl.dropbox.com/u/17084229/BGRALazResStream7z.7z

I was creating TBGRAImage after loading it from stream. Now switched those lines,but still I guess I need to use a
Handler in LoadFromStream function. I get execption "Unknown/Unsupported PCX image type" . I am actually loading a PNG from TLazarusResourceStream.
Title: Re: BGRABitmap tutorial
Post by: CaptBill on April 03, 2011, 08:01:48 pm
Thanks Circular.

Just what i needed.

Nice work.
Title: Re: BGRABitmap tutorial
Post by: circular on April 03, 2011, 08:15:07 pm
Ok Gintas, I suppose the PCX reader tries to read it. In BGRADefaultBitmap, the PCX files are registered in the initialisation section. You may remove it.
Title: Re: BGRABitmap tutorial
Post by: Gintas on April 04, 2011, 06:53:54 pm
 :'( Well it doesn't works,even if I remove that PCX and XPM readers code.  Now I get "JPEG Error".
Can you give me more info about Handler parameter in this function?
Code: [Select]
  procedure LoadFromStream(Str: TStream; Handler: TFPCustomImageReader);
Title: Re: BGRABitmap tutorial
Post by: circular on April 04, 2011, 07:59:16 pm
It's the FreePascal handler. You're right, if you give the right handler as a parameter, you won't have the error with "PCX" or "JPG".

You need to create the reader :
Quote
uses FPReadPNG;

{$R *.lfm}


{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
var
  reader: TFPReaderPNG;
begin
  GradBMP:=TBGRABitmap.Create(Width,Height);

  reader := TFPReaderPNG.Create;
  Red:=TBGRABitmap.Create; //don't need to initialize size here
  Red.LoadFromStream(TLazarusResourceStream.Create('splash_logo','PNG'),reader);
  reader.Free;
end;  
Title: Re: BGRABitmap tutorial
Post by: Gintas on April 04, 2011, 09:25:26 pm
Thanks for code! It worked like a charm and now I can store all the graphics inside executable.  :)
*happy dance*
Title: Re: BGRABitmap tutorial
Post by: circular on April 05, 2011, 05:48:45 pm
Cool.

The tutorial is in german thanks to Billyraybones and Lainz, and now it is in French too.
http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial/fr
Title: Re: BGRABitmap tutorial
Post by: lainz on April 06, 2011, 08:04:10 pm
Cool.

The tutorial is in german thanks to Billyraybones and Lainz, and now it is in French too.
http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial/fr

Thanks to Billyraybones, I just did the index-
Title: Re: BGRABitmap tutorial
Post by: gyts on April 07, 2011, 10:26:59 pm
Cool.

The tutorial is in german thanks to Billyraybones and Lainz, and now it is in French too.
http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial/fr

Please do tutorials how to use functions showed in no6, 7, 8, 9, 10, 14, 15 tests of bgrafunctest
Title: Re: BGRABitmap tutorial
Post by: circular on April 07, 2011, 11:15:21 pm
test n°6: resample, it's in tutorial 2.
test n°7: smart zoom 3 and rotate, tutorial to do
test n°8: global opacity and background scrolling, tutorial to do
test n°9: mask, in tutorial 5 (DrawSun)
test n°10: direct pixel access, in tutorial 4
test n°14: layer blending, in tutorial 5 (ApplyLight)
test n°15: phong shading and perlin noise, in tutorial 9

so in fact, there could be a new tutorial :
- on filters (zoom, rotate, and others)
- global opacity
- background scrolling

It would be useful to add another tutorial about layers, how to blend transparent layers, so it would include global opacity.

Maybe you mean that some aspects are not developped enough in tutorials.
Title: Re: BGRABitmap tutorial
Post by: gyts on April 08, 2011, 09:12:55 am
Maybe you mean that some aspects are not developped enough in tutorials.

Yes. It's too complicated for me.
Title: Re: BGRABitmap tutorial
Post by: circular on April 08, 2011, 05:06:47 pm
I added mask explanations : http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_5

Is this what you need ?

If that's the case, can you tell me precisely what sections of the tutorials you would like to be expanded ?
Title: Re: BGRABitmap tutorial
Post by: mica on April 08, 2011, 06:08:22 pm
Little OT:
Thanks for all the great Tutorials :)
Title: Re: BGRABitmap tutorial
Post by: circular on April 08, 2011, 10:20:25 pm
Thanks.

I've updated BGRABitmap with some fixes (on subversion and in LazPaint 3.1 archive) :
- IBGRAScanner for texture and gradient
- phong precise map
- gtk bug fix
- fill poly optimization (faster polylines, for example curve in lazpaint)
- roundcap uturns fix
Title: Re: BGRABitmap tutorial
Post by: lainz on April 09, 2011, 12:28:49 am
I can't access the wiki.  %)
I remember some BGRABitmap tutorial about masks or something related..

Code: [Select]
function Shadow(ASource: TBGRABitmap; AOffSetX,AOffSetY: Integer; ARadius: Integer; AShowSource: Boolean = True): TBGRABitmap;
var
  bmpOut: TBGRABitmap;
begin
  bmpOut:= TBGRABitmap.Create(ASource.Width+2*ARadius+AOffSetX,ASource.Height+2*ARadius+AOffSetY);

  bmpOut.PutImage(ARadius+AOffSetX,ARadius+AOffSetY,ASource,dmDrawWithTransparency);

  BGRAReplace(bmpOut,bmpOut.FilterBlurRadial(ARadius,rbFast));

  if AShowSource = True then bmpOut.PutImage(ARadius,ARadius,ASource,dmDrawWithTransparency);

  Result:= bmpOut;
end;   

I need to fill with color the visible area of the bitmap 'ASource' and then apply the blur effect to make the shadow of a certain color.
Title: Re: BGRABitmap tutorial
Post by: circular on April 09, 2011, 09:34:54 am
So you need to set the color without changing the alpha channel. To do this :
Code: [Select]
var
  n: integer;
  p: PBGRAPixel;
begin
  p := image.Data;
  for n := 1 to p.NbPixels do
  begin
    if p^.alpha <> 0 then
    begin
      p^.red := wantedColor.red;
      p^.green := wantedColor.green;
      p^.blue := wantedColor.blue;
    end;
    inc(p);
  end;
end;
Title: Re: BGRABitmap tutorial
Post by: lainz on April 09, 2011, 11:24:47 pm
Thankyou circular!

Here is the Shadow function:

Code: Pascal  [Select][+][-]
  1. function Shadow(ASource: TBGRABitmap; AShadowColor: TBGRAPixel; AOffSetX,AOffSetY: Integer; ARadius: Integer; AShowSource: Boolean = True): TBGRABitmap;
  2. var
  3.   bmpOut: TBGRABitmap;
  4.   n: integer;
  5.   p: PBGRAPixel;
  6. begin
  7.   bmpOut:= TBGRABitmap.Create(ASource.Width+2*ARadius+AOffSetX,ASource.Height+2*ARadius+AOffSetY);
  8.  
  9.   bmpOut.PutImage(AOffSetX,AOffSetY,ASource,dmDrawWithTransparency);
  10.  
  11.   p := bmpOut.Data;
  12.   for n := 1 to bmpOut.NbPixels do begin
  13.    if p^.alpha <> 0 then begin
  14.       p^.red := AShadowColor.red;
  15.       p^.green := AShadowColor.green;
  16.       p^.blue := AShadowColor.blue;
  17.     end;
  18.     inc(p);
  19.   end;
  20.  
  21.   BGRAReplace(bmpOut,bmpOut.FilterBlurRadial(ARadius,rbFast));
  22.  
  23.   if AShowSource = True then bmpOut.PutImage(0,0,ASource,dmDrawWithTransparency);
  24.  
  25.   Result:= bmpOut;
  26. end;      

Now i can acces the wiki, with same code in Tutorial5 'sky with a moon' adding:

Code: Pascal  [Select][+][-]
  1. layer:= Shadow(layer,BGRABlack,5,5,5);

You can obtain a shadow like in the attached image.
Title: Re: BGRABitmap tutorial
Post by: circular on April 10, 2011, 12:14:31 am
Cool.

Note that to avoid memory leak you should write :
Code: Pascal  [Select][+][-]
  1.    BGRAReplace(layer,Shadow(layer,BGRABlack,5,5,5));  
Title: Re: BGRABitmap tutorial
Post by: circular on April 11, 2011, 06:38:04 pm
Hello,

I've added a new tutorial about texture mapping :

http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_10

Enjoy  :)
Title: Re: BGRABitmap tutorial
Post by: VTwin on April 11, 2011, 08:14:29 pm
Hello Circular,

I'm getting errors in trying to compile 3.2:

Code: [Select]
bgrabitmaptypes.pas(370,6) Error: No matching implementation for interface method "IUnknown.QueryInterface(const TGuid,out <Formal type>):LongInt; StdCall;" found
bgrabitmaptypes.pas(370,6) Error: No matching implementation for interface method "IUnknown._AddRef:LongInt; StdCall;" found
bgrabitmaptypes.pas(370,6) Error: No matching implementation for interface method "IUnknown._Release:LongInt; StdCall;" found
bgrabitmaptypes.pas(437,6) Error: No matching implementation for interface method "IUnknown.QueryInterface(const TGuid,out <Formal type>):LongInt; StdCall;" found
bgrabitmaptypes.pas(437,6) Error: No matching implementation for interface method "IUnknown._AddRef:LongInt; StdCall;" found
bgrabitmaptypes.pas(437,6) Error: No matching implementation for interface method "IUnknown._Release:LongInt; StdCall;" found
bgrabitmaptypes.pas(439,1) Fatal: There were 6 errors compiling module, stopping

2.8 is working well. Any thoughts?

Frederick


Carbon Widgets on Intel OS X 10.6
Title: Re: BGRABitmap tutorial
Post by: circular on April 11, 2011, 09:57:38 pm
Clearly the interface IBGRAScanner doesn't compile.

Maybe it could work by replacing IFNDEF WINDOWS by IFDEF UNIX. It should occur 12 times.

Or maybe by removing stdcall and cdecl keywords in the implementation section.

Or by using only these definitions (in implementation too) :
Quote
          function QueryInterface(const iid : tguid;out obj) : longint;stdcall;
          function _AddRef : longint;stdcall;
          function _Release : longint;stdcall;

Without any IFDEFs. In fact, I don't know if the IFDEFs are necessary at all.
Title: Re: BGRABitmap tutorial
Post by: VTwin on April 13, 2011, 12:43:17 am
Clearly the interface IBGRAScanner doesn't compile.

Maybe it could work by replacing IFNDEF WINDOWS by IFDEF UNIX. It should occur 12 times.

Or maybe by removing stdcall and cdecl keywords in the implementation section.

Or by using only these definitions (in implementation too) :
Quote
          function QueryInterface(const iid : tguid;out obj) : longint;stdcall;
          function _AddRef : longint;stdcall;
          function _Release : longint;stdcall;

Without any IFDEFs. In fact, I don't know if the IFDEFs are necessary at all.

Thanks circular,

Should I be trying these out, or are they likely to be fixed in a new release?

Cheers,
Frederick
Title: Re: BGRABitmap tutorial
Post by: circular on April 13, 2011, 04:00:57 pm
Well, please try and tell me so I will know what to put in a next release.
Title: Re: BGRABitmap tutorial
Post by: circular on April 13, 2011, 04:25:45 pm
I added a new tutorial about combining scanner transformations (works with last archive LazPaint3.3) :
http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_11
Title: Re: BGRABitmap tutorial
Post by: rajivsoft on April 13, 2011, 06:49:36 pm
Hello Circular,

I'm getting errors in trying to compile 3.2:

Code: [Select]
bgrabitmaptypes.pas(370,6) Error: No matching implementation for interface method "IUnknown.QueryInterface(const TGuid,out <Formal type>):LongInt; StdCall;" found
bgrabitmaptypes.pas(370,6) Error: No matching implementation for interface method "IUnknown._AddRef:LongInt; StdCall;" found
bgrabitmaptypes.pas(370,6) Error: No matching implementation for interface method "IUnknown._Release:LongInt; StdCall;" found
bgrabitmaptypes.pas(437,6) Error: No matching implementation for interface method "IUnknown.QueryInterface(const TGuid,out <Formal type>):LongInt; StdCall;" found
bgrabitmaptypes.pas(437,6) Error: No matching implementation for interface method "IUnknown._AddRef:LongInt; StdCall;" found
bgrabitmaptypes.pas(437,6) Error: No matching implementation for interface method "IUnknown._Release:LongInt; StdCall;" found
bgrabitmaptypes.pas(439,1) Fatal: There were 6 errors compiling module, stopping

2.8 is working well. Any thoughts?

Frederick

Carbon Widgets on Intel OS X 10.6

Same problem here wit 3.3 version and another:

/Developer/lazarus/components/bgrabitmap/bgradnetdeserial.pas(74,14) Error: There is no method in an ancestor class to be overridden: "TDotNetDeserialization.ToString:AnsiString;"

and

/Developer/lazarus/components/bgrabitmap/bgrapaintnet.pas(19,14) Error: There is no method in an ancestor class to be overridden: "TPaintDotNetFile.ToString:AnsiString;"

replace {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF} with stdcall and cut away override; helped to compile it
Title: Re: BGRABitmap tutorial
Post by: circular on April 13, 2011, 09:40:17 pm
Ok I'll try putting stdcall for the 3 functions.

About the ToString problem, I suppose that you don't have version 0.9.30.

Title: Re: BGRABitmap tutorial
Post by: Sternas Stefanos on April 14, 2011, 12:17:58 am
unit BGRABitmapTypes;
....
//interface
     function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid: tguid; out obj): longint;{$IFDEF WINDOWS}stdcall{$ELSE}CDecl{$ENDIF};
     function _AddRef: longint;{$IFDEF WINDOWS}stdcall{$ELSE}CDecl{$ENDIF};
     function _Release: longint;{$IFDEF WINDOWS}stdcall{$ELSE}CDecl{$ENDIF};
Title: Re: BGRABitmap tutorial
Post by: circular on April 14, 2011, 12:42:06 am
Are you sure about this ?

I've searched FreePascal source code, and it's stdcall everywhere.
Title: Re: BGRABitmap tutorial
Post by: Leledumbo on April 14, 2011, 03:43:16 am
http://wiki.lazarus.freepascal.org/User_Changes_Trunk#IInterface.QueryInterface.2C_._AddRef_and_._Release_definitions_have_been_changed (http://wiki.lazarus.freepascal.org/User_Changes_Trunk#IInterface.QueryInterface.2C_._AddRef_and_._Release_definitions_have_been_changed)
Title: Re: BGRABitmap tutorial
Post by: circular on April 14, 2011, 11:49:53 am
Thanks Leledumbo. So the correct code now is :

Code: [Select]
function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} IID: TGUID; out Obj): HResult; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND}; override;
function _AddRef: Integer; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND}; override;
function _Release: Integer; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND}; override;

Edit: in fact in BGRABitmap there is not "override" because it does not replace an ancestor method.
Title: Re: BGRABitmap tutorial
Post by: rajivsoft on April 14, 2011, 02:50:59 pm
Ok I'll try putting stdcall for the 3 functions.

About the ToString problem, I suppose that you don't have version 0.9.30.
I have official 0.9.30 (2011-04-13), fpc v:2.4.0, svn rev:30219, i386-darwin-carbon
Title: Re: BGRABitmap tutorial
Post by: circular on April 14, 2011, 03:39:15 pm
Strange. Ok, so I'll remove the override. It can work without it anyway.
Title: Re: BGRABitmap tutorial
Post by: rajivsoft on April 14, 2011, 04:27:34 pm
Thanks Leledumbo. So the correct code now is :

Code: [Select]
function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} IID: TGUID; out Obj): HResult; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND}; override;
function _AddRef: Integer; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND}; override;
function _Release: Integer; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND}; override;

Edit: in fact in BGRABitmap there is not "override" because it does not replace an ancestor method.
This one works, but again, without override;
Title: Re: BGRABitmap tutorial
Post by: circular on April 14, 2011, 04:36:49 pm
Yep.
Title: Re: BGRABitmap tutorial
Post by: martinrame on April 18, 2011, 11:28:07 pm
Hi, I would like to know if TBGRABitmap has a way to load RAW images from a memory buffer or stream.

Title: Re: BGRABitmap tutorial
Post by: Shebuka on April 19, 2011, 10:06:36 am
Hi, I would like to know if TBGRABitmap has a way to load RAW images from a memory buffer or stream.
It has LoadFromStream procedure and i think that if LoadFromFile accepts like all common image formats, also LoadFromStream must accept all common formats.
Title: Re: BGRABitmap tutorial
Post by: martinrame on April 19, 2011, 02:46:39 pm
Thanks Shebuka, the problem here is that I'm trying to load a not so common format.

I only know the buffer size, width, height, and bit depth of the raw data, and like to load into a TBRABitmap to show on screen. Is this possible?.
Title: Re: BGRABitmap tutorial
Post by: VTwin on April 19, 2011, 03:11:00 pm
circular,

I just tried version 3.4, and it works fine, many thanks for the fixes.

Can you tell me what unit BGRABitmap uses to read a png? There seems to be a bug in the png import, and I'm not sure how to report it. I apologize for not being able to figure it out myself.

Some png files created in Photoshop, which open fine in browsers and other image viewing programs, do not open correctly.

Thanks for the fantastic work on BGRABitmap.

Cheers,
Frederick


EDIT: It may be related to 16 bit versus 8 bit pngs.
Title: Re: BGRABitmap tutorial
Post by: martinrame on April 19, 2011, 04:36:36 pm
Frederick, I use a TPNGReader to load PNGs. Hope this code helps you:

var
  lPngReader: TFPReaderPNG;
begin
  inherited Create(TheOwner);
  FBMP := TBGRABitmap.Create;

  lPngReader := TFPReaderPNG.create;
  try
    FBMP.LoadFromFile('myPng.png', lPngReader);
  finally
    FBMP.Free;
    lPngReader.Free;
  end;
Title: Re: BGRABitmap tutorial
Post by: martinrame on April 19, 2011, 05:10:09 pm
Circular, using the code below I can load a raw bitmap image from a pointer to an UInt8 array I get from a C++ medical library. The problem is that the images have different bit depths. They can be of 8,10,12,13,16 bits.

Using the code below, I can load the majority of images, but some of them (the color images).

I attached two files, a jpg generated by TBGRabitmap that is wrong, and the version I'm getting with TImageEn (a Delphi library). Please tell me if you need the original raw image file for testing, I can't upload here because of attachment size restrictions.

Finally, my question is, how can I show correctly my image with TBGRABitmap?

Code: [Select]
      lBmp := TBGRABitmap.Create(FImgWidth, FImgHeight);
      try
        for y := 0 to FImgHeight-1 do
        begin
          p := lBmp.Scanline[y];
          for x := 0 to FImgWidth-1 do
          begin
            p^.red := lBuffer[0];
            p^.green := lBuffer[1];
            p^.blue := lBuffer[2];
            p^.alpha:= 255;
            inc(p);
            inc(lBuffer);
          end;
        end;
        lBmp.Draw(Self.Canvas, 0, 0);
      finally
        lbmp.Free;
      end; 

moderation note:
When posting examples or attachments, please anonimize them. The original images contained patient info.
Title: Re: BGRABitmap tutorial
Post by: circular on April 19, 2011, 06:12:57 pm
circular,

I just tried version 3.4, and it works fine, many thanks for the fixes.

Can you tell me what unit BGRABitmap uses to read a png? There seems to be a bug in the png import, and I'm not sure how to report it. I apologize for not being able to figure it out myself.

Some png files created in Photoshop, which open fine in browsers and other image viewing programs, do not open correctly.
The LoadFromFile functions just calls the standard LoadFromFile functions of FPImage which uses TPNGReader. There is nothing specific here when loading bitmaps. But when saving, I specified that it should use 8-bit channels, because some programs cannot read 16-bit channels.
Title: Re: BGRABitmap tutorial
Post by: circular on April 19, 2011, 06:25:39 pm
Circular, using the code below I can load a raw bitmap image from a pointer to an UInt8 array I get from a C++ medical library. The problem is that the images have different bit depths. They can be of 8,10,12,13,16 bits.

Finally, my question is, how can I show correctly my image with TBGRABitmap?
You need to determine the red/green/blue values before assigning them to the bitmap. The code you supplied is perfect for 24-bit RGB images, but of course, it does not work for other formats.

For example, if you have 16-bit RGB image, you need to get the bits that define red value, green value and blue value.

If you have 16-bit grayscale image, you can just use a PWord and divide it by 256 :
Code: [Select]
var PWordBuffer : PWord;

begin
   ...
        for y := 0 to FImgHeight-1 do
        begin
          p := lBmp.Scanline[y];
          for x := 0 to FImgWidth-1 do
          begin
            byteValue := PWordBuffer^ shr 8; //means div 256
            p^.red := byteValue;
            p^.green := byteValue;
            p^.blue := byteValue;
            p^.alpha:= 255;
            inc(p);
            inc(PWordBuffer);
          end;
        end;

You may also use TLazInfImage to do the conversion :
Code: [Select]
var img: TLazIntfImage;
  descr: TRawImageDescription;
  p: PByte;
  x,y: integer;
begin
  img := TLazIntfImage.Create(0,0);
  fillchar(descr,sizeof(descr),0);
  descr.BitsPerPixel := 8;
  descr.Format := ricfGray;
  descr.RedPrec := 8;  //red channel is used to store grayscale value
  descr.Width := 16;
  descr.Height := 16;
  img.DataDescription := descr; //this allocates the bitmap
  for y := 0 to 15 do
  begin
    p := img.GetDataLineStart(y);
    //here you can load the real data instead of this loop
    for x := 0 to 15 do
    begin
      p^ := x*16;
      inc(p);
    end;
  end;
  bmp := TBGRABitmap.Create(img.Width,img.Height);
  for y := 0 to 15 do
    for x := 0 to 15 do
      bmp.SetPixel(x,y,FPColorToBGRA(img.Colors[x,y]));
  img.free;
end;
Title: Re: BGRABitmap tutorial
Post by: martinrame on April 19, 2011, 07:43:03 pm
Thanks Circular.

I tested your suggestion about (PWordBuffer^ shr 8) for 16bit grayscale images, but it doesn't show correctly, it shows the image duplicated at the right side of the first image.

Regarding 16bit RGB images, I don't know where to start looking for the rgb values.

The duplication appeared after I replaced the type of the buffer from PByte to PWord.
Title: Re: BGRABitmap tutorial
Post by: martinrame on April 19, 2011, 09:07:44 pm
I found a solution for the RGB problem, the pointer to the buffer must be incremented by 3 instead of 1.

Here's the new code:

Code: [Select]
        for y := 0 to FImgHeight - 1 do
        begin
          p := lBmp.Scanline[y];
          for x := 0 to FImgWidth - 1 do
          begin
            p^.red := lBuffer[2];
            p^.green := lBuffer[1];
            p^.blue := lBuffer[0];
            p^.alpha := 255;
            Inc(p);
            Inc(lBuffer, 3);
          end;
        end; 

Now I only have to figure out how to elimnate the duplicated images when working with 16bits grayscale images.
Title: Re: BGRABitmap tutorial
Post by: circular on April 19, 2011, 09:42:26 pm
I found a solution for the RGB problem, the pointer to the buffer must be incremented by 3 instead of 1.
The color are rendered correctly ?
It means that there are 9 bytes per pixel, so maybe 3 bytes per channel.

Quote
Now I only have to figure out how to elimnate the duplicated images when working with 16bits grayscale images.
Do you have a screenshot with PByte and PWord ?
Title: Re: BGRABitmap tutorial
Post by: martinrame on April 19, 2011, 09:52:30 pm
Quote
The color are rendered correctly ?

Here's the correct screenshot:

http://www.tarjeta-salud.com.ar/img/test-correcto.jpg

Quote
Do you have a screenshot with PByte and PWord ?

PByte: http://www.tarjeta-salud.com.ar/img/test-pbyte.jpg
PWord: http://www.tarjeta-salud.com.ar/img/test-pword.jpg
Title: Re: BGRABitmap tutorial
Post by: lainz on April 19, 2011, 10:59:03 pm
How i can create Outline text with BGRABitmap?
Title: Re: BGRABitmap tutorial
Post by: circular on April 20, 2011, 12:09:53 pm
Quote
Do you have a screenshot with PByte and PWord ?

PByte: http://www.tarjeta-salud.com.ar/img/test-pbyte.jpg
PWord: http://www.tarjeta-salud.com.ar/img/test-pword.jpg
Clearly this image is 8-bit grayscale and PByte is the right way to read it.
Title: Re: BGRABitmap tutorial
Post by: circular on April 20, 2011, 12:32:51 pm
How i can create Outline text with BGRABitmap?
It's not easy, because it uses the bitmap result from the operating system, it does not have access to the geometry of the font. Anyway you can make some outline by using the contour filter :

Code: [Select]
uses Types;

procedure TForm1.FormPaint(Sender: TObject);
const textContent = 'Some text'; fontheight = 30;
var image,textBmp,outline: TBGRABitmap;
    size: TSize;
    p: PBGRAPixel;
    n: Integer;
begin
  image := TBGRABitmap.Create(ClientWidth,ClientHeight, ColorToBGRA(ColorToRGB(clBtnFace)) );

  //define font param
  image.FontAntialias := true;
  image.FontHeight := fontheight;
  image.FontStyle := [fsBold];

  //create text image
  size := image.TextSize(textContent);
  textBmp := TBGRABitmap.Create(size.cx+2,size.cy+2,BGRAWhite);
  image.CopyPropertiesTo(textBmp);
  textBmp.TextOut(1,1,textContent,BGRABlack);

  //create outline
  outline := textbmp.FilterContour as TBGRABitmap;
  textBmp.Free;
  p := outline.data;
  for n := 0 to outline.NbPixels-1 do
  begin
    p^.alpha := 255-(GammaExpansionTab[p^.red] shr 8);
    p^.red := 0; //outline color
    p^.green := 0;
    p^.blue := 192;
    inc(p);
  end;

  //draw outline
  image.PutImage(20-1,20-1,outline,dmDrawWithTransparency);
  outline.Free;

  //draw inner text
  image.TextOut(20,20,textContent,BGRAWhite);

  image.Draw(Canvas,0,0,True);
  image.free;
end; 
Title: Re: BGRABitmap tutorial
Post by: martinrame on April 20, 2011, 02:05:58 pm
Circular, I measured the time it takes to load the buffer image to a TBGRABitmap and it's very fast, congratulations!.

Now, if I do myBGRABitmap.Draw(Image1.Canvas, 0, 0); it takes too much time (2 seconds for a 4000x4000 image is too much).

What component do you recommend to paint to, instead of TImage?. I use a TScrollBox with a TImage as child, that allows me to scroll the image.
Title: Re: BGRABitmap tutorial
Post by: VTwin on April 20, 2011, 03:57:58 pm
The LoadFromFile functions just calls the standard LoadFromFile functions of FPImage which uses TPNGReader. There is nothing specific here when loading bitmaps. But when saving, I specified that it should use 8-bit channels, because some programs cannot read 16-bit channels.

Thanks martinrame and circular,

I tried a tutorial I found here:
 
http://fpc-docs.gorilla3d.com/built-in-units/fcl-image/opening-an-image

TFPReaderPNG does seem to have trouble with 16-bit channels. I'm not sure if it is a bug, or a feature that should be requested. I'll look into it more. Maybe someone here knows more about it?

Cheers,
Frederick
Title: Re: BGRABitmap tutorial
Post by: VTwin on April 20, 2011, 04:02:32 pm
Circular, I measured the time it takes to load the buffer image to a TBGRABitmap and it's very fast, congratulations!.

Now, if I do myBGRABitmap.Draw(Image1.Canvas, 0, 0); it takes too much time (2 seconds for a 4000x4000 image is too much).

What component do you recommend to paint to, instead of TImage?. I use a TScrollBox with a TImage as child, that allows me to scroll the image.

I've been using:

fBitmap.Draw(fImage.Picture.Bitmap.Canvas, x, y, fOpaque);

Does that help any?

Frederick
Title: Re: BGRABitmap tutorial
Post by: martinrame on April 20, 2011, 04:29:06 pm
Thanks Frederick:

Quote
fBitmap.Draw(fImage.Picture.Bitmap.Canvas, x, y, fOpaque);

No, I get the same time as in fImage.Canvas.
Title: Re: BGRABitmap tutorial
Post by: circular on April 20, 2011, 06:24:49 pm
martinrame, you can use a PaintBox and draw only the visible part of the bitmap (in an OnPaint event). You can add two scrollbars and set the max value to the appropriate value (the size of the image minus the size of the visible area) and handle the OnChange event to update the visible part.

When drawing the visible part, you can use GetPart function of BGRABitmap and free it afterwards :
Code: [Select]
tempBmp := myFullBitmap.GetPart(Rect(ScrollX,ScrollY,ScrollX+VisibleWidth,ScrollY+VisibleHeight)) as TBGRABitmap;
tempBmp.Draw(myPaintBox.Canvas,0,0);
tempBmp.Free;
Title: Re: BGRABitmap tutorial
Post by: Dibo on April 20, 2011, 07:03:02 pm
Hi,

I am trying draw simple gradient:
Code: Pascal  [Select][+][-]
  1. FBGRA.Canvas.GradientFill(ClientRect,clRed,clSilver,gdHorizontal);
  2. FBGRA.Draw(Self.Canvas,0,0,False);    
  3.  
I have questions:
1. How to draw gradient with low quality (less pass colors)
2. There is gdHorizontal and gdVertical style but how create gradient from top-left to bottom-right?
Title: Re: BGRABitmap tutorial
Post by: lainz on April 20, 2011, 08:12:12 pm
Hi,

I am trying draw simple gradient:
Code: Pascal  [Select][+][-]
  1. FBGRA.Canvas.GradientFill(ClientRect,clRed,clSilver,gdHorizontal);
  2. FBGRA.Draw(Self.Canvas,0,0,False);    
  3.  
I have questions:
1. How to draw gradient with low quality (less pass colors)
2. There is gdHorizontal and gdVertical style but how create gradient from top-left to bottom-right?

Use GradientFill function from BGRABitmap, not GradientFill from Canvas.

bmp: BGRABitmap;

bmp.GradientFill instead bmp.Canvas.GradientFill

And you can set coordinates of the gradient.

See this example with a radial gradient:
http://wiki.lazarus.freepascal.org/Sample_Graphics#Lazarus_About
Title: Re: BGRABitmap tutorial
Post by: circular on April 20, 2011, 09:17:21 pm
If you want to do a gradient with low quality, you can draw it with dark colors, and then apply Normalize filter :
Code: [Select]
  image.GradientFill(...);
  BGRAReplace(image, image.FilterNormalize);
Title: Re: BGRABitmap tutorial
Post by: circular on April 20, 2011, 09:27:16 pm
Hello people. I've added Mitchell and Spline resample filter. Simply write:
Code: [Select]
image.ResampleFilter := rfSpline;  
stretched := image.Resample(newWidth, newHeight) as TBGRABitmap;  

There is also BestQuality, which takes Mitchell for downsizing and Spline for upsizing :
Code: [Select]
image.ResampleFilter := rfBestQuality;  
stretched := image.Resample(newWidth, newHeight) as TBGRABitmap;  

By the way, thank you all for your support.

You can find these new filters in the last version (LazPaint3.6 archive)
Title: Re: BGRABitmap tutorial
Post by: Dibo on April 20, 2011, 09:30:36 pm
Hi,

I am trying draw simple gradient:
Code: Pascal  [Select][+][-]
  1. FBGRA.Canvas.GradientFill(ClientRect,clRed,clSilver,gdHorizontal);
  2. FBGRA.Draw(Self.Canvas,0,0,False);    
  3.  
I have questions:
1. How to draw gradient with low quality (less pass colors)
2. There is gdHorizontal and gdVertical style but how create gradient from top-left to bottom-right?

Use GradientFill function from BGRABitmap, not GradientFill from Canvas.

bmp: BGRABitmap;

bmp.GradientFill instead bmp.Canvas.GradientFill

And you can set coordinates of the gradient.

See this example with a radial gradient:
http://wiki.lazarus.freepascal.org/Sample_Graphics#Lazarus_About

Thanks
If you want to do a gradient with low quality, you can draw it with dark colors, and then apply Normalize filter :
Code: [Select]
  image.GradientFill(...);
  BGRAReplace(image, image.FilterNormalize);
And thanks too :)
Title: Re: BGRABitmap tutorial
Post by: martinrame on April 21, 2011, 02:18:43 am
Thanks Cicular for the tip about Paintbox and onPaint. Now I can handle big images smoothly.

Now I have a new question. How can I zoom my image?.
Title: Re: BGRABitmap tutorial
Post by: circular on April 21, 2011, 10:37:18 am
To zoom images, you need to work as if the visible area were smaller.

Code: [Select]
ScrollHoriz.Max := Round(VisibleWidth/ZoomFactor) - PaintBox1.Width;
...

And when drawing use resample :
Code: [Select]
tempBmp := myFullBitmap.GetPart(Rect(ScrollX,ScrollY,ScrollX+Round(VisibleWidth/ZoomFactor),ScrollY+ound(VisibleHeight/ZoomFactor))) as TBGRABitmap;
stretched := tempBmp.Resample(VisibleWidth,VisibleHeight,rmFineResample);
tempBmp.Draw(myPaintBox.Canvas,0,0);
stretched.Free;
tempBmp.Free;

You can use rmSimpleStretch or change ResampleFilter property to change the way it is stretched.
Title: Re: BGRABitmap tutorial
Post by: martinrame on April 21, 2011, 03:39:34 pm
Thanks Circular!
Title: Re: BGRABitmap tutorial
Post by: circular on April 21, 2011, 06:08:13 pm
You're welcome.
Title: Re: BGRABitmap tutorial
Post by: lainz on April 24, 2011, 09:52:51 pm
How I can assign a TBGRABitmap to a TImage?

Edit: I got it. But there is a better way?

Code: Pascal  [Select][+][-]
  1. bmp:= TBGRABitmap.Create(Image1.Width,Image1.Height);
  2. bmp.Rectangle(Image1.ClientRect,BGRABlack,BGRAWhite,dmDrawWithTransparency);
  3. Image1.Picture.Bitmap.LoadFromBitmapHandles(bmp.Bitmap.BitmapHandle,bmp.Bitmap.BitmapHandle);
  4. bmp.Free;
Title: Re: BGRABitmap tutorial
Post by: circular on April 25, 2011, 01:17:32 pm
Good question. I had some problems with TBitmap.Assign(TBGRABitmap.Bitmap). I do not know how to solve this. Maybe we could add TBGRABitmap.AssignTo(TBitmap)

By the way, I suppose the second parameter of LoadFromBitmapHandles is the mask handle, then I suppose it should be zero.
Title: Re: BGRABitmap tutorial
Post by: circular on April 25, 2011, 11:19:00 pm
I've added comments in BGRABitmap source code. If you're curious to understand how BGRABitmap works, download last LazPaint zip file (3.7) or update to last subversion.
https://sourceforge.net/projects/lazpaint/files/src/
Title: Re: BGRABitmap tutorial
Post by: martinrame on April 26, 2011, 01:55:54 am
Hi Circular. I'm struggling to find some pointers about line/glyph picking.

I would like to draw something over a bitmap, like a line or text and let the user pick it and move it around with the mouse.

How can I do this?
Title: Re: BGRABitmap tutorial
Post by: Shebuka on April 26, 2011, 10:18:56 am
How I can assign a TBGRABitmap to a TImage?

Edit: I got it. But there is a better way?

Code: Pascal  [Select][+][-]
  1. bmp:= TBGRABitmap.Create(Image1.Width,Image1.Height);
  2. bmp.Rectangle(Image1.ClientRect,BGRABlack,BGRAWhite,dmDrawWithTransparency);
  3. Image1.Picture.Bitmap.LoadFromBitmapHandles(bmp.Bitmap.BitmapHandle,bmp.Bitmap.BitmapHandle);
  4. bmp.Free;

This is a part of code i'using for my software internal image viewer and it work perfect with .Assign , hope it helps.
Code: Pascal  [Select][+][-]
  1. uses
  2.   Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  3.   ExtCtrls, ComCtrls, BGRABitmap, BGRABitmapTypes;
  4.  
  5. ...
  6.  
  7.   private
  8.     { private declarations }
  9.     FImage: TBGRABitmap;
  10.     FCurrImagePath: String;
  11.  
  12. procedure TFrm_ImageView.FormCreate(Sender: TObject);
  13. begin
  14.   FImage := TBGRABitmap.Create(100, 100, clButton);
  15.   FImage.ResampleFilter := rfCosine;
  16. end;
  17.  
  18. procedure TFrm_ImageView.ShowImage(const AFileName: String);
  19. begin
  20.   FImage.LoadFromFile(AFileName);
  21.   RepaintNewImage();
  22. end;
  23.  
  24. procedure TFrm_ImageView.RepaintNewImage();
  25. var
  26.   stretched: TBGRABitmap;
  27. begin
  28.   try
  29.     stretched := FImage.Resample(Img_View.Width, Img_View.Height, rmFineResample) as TBGRABitmap;
  30.     Img_View.Picture.Bitmap.Assign(stretched.Bitmap);
  31.   finally
  32.     stretched.Free;
  33.   end;
  34. end;
Title: Re: BGRABitmap tutorial
Post by: circular on April 26, 2011, 01:32:47 pm
Hi Circular. I'm struggling to find some pointers about line/glyph picking.

I would like to draw something over a bitmap, like a line or text and let the user pick it and move it around with the mouse.

How can I do this?

You need to handle MouseDown, MouseMove and MouseUp events. Save the previous mouse position, compute the difference, and add it to the current position of the moving part. Use a boolean to know if the user is dragging or not. Update with a call to Invalidate/Repaint or use a PaintBox.
Title: Re: BGRABitmap tutorial
Post by: martinrame on April 26, 2011, 03:54:56 pm
Thanks, that's the easy part. But, how can I know if the object below the mouse pointer is a movable object instead of the background image.

Let me clarify this. I have a background layer with an image, and a foreground layer containing objects drawn by the user, such as text, arrows, lines. I wan to let the user to pick any of those objects and move around with the mouse.
Title: Re: BGRABitmap tutorial
Post by: circular on April 26, 2011, 05:22:05 pm
If it's stored as a bitmap, you can do a getpixel and check alpha value.

If it's not, then you need to do some vectorial tests. Maybe you can just test if the mouse pointer is in the bounding rectangle. If not, you can use some functions in BGRABitmapTypes likes :

function IntersectLine(line1, line2: TLineDef): TPointF;
function IntersectLine(line1, line2: TLineDef; out parallel: boolean): TPointF;
function IsConvex(const pts: array of TPointF): boolean;
function DoesQuadIntersect(pt1,pt2,pt3,pt4: TPointF): boolean;
function DoesSegmentIntersect(pt1,pt2,pt3,pt4: TPointF): boolean;

You may need to create new ones, for example to test if a point is on a segment of a certain width.
Title: Re: BGRABitmap tutorial
Post by: Gintas on April 26, 2011, 09:39:09 pm
A tutorial for Knob spin control would be nice. I see that LazPaint uses something like knobs in a filter dialogs,but still without any images. 
Title: Re: BGRABitmap tutorial
Post by: circular on April 27, 2011, 07:31:44 am
It's a good idea. But there is no general way to handle geometrical issues, except by using a vectorial framework. Maybe fpVectorial could be developped in that direction ?
Title: Re: BGRABitmap tutorial
Post by: circular on April 28, 2011, 04:15:57 pm
Hello people.

I've added CanvasBGRA property to BGRABitmap. It works like a standard canvas, except with antialiasing and opacity options, so you can cut'n'paste existing drawing code.

It's available on subversion (BGRABitmap v3.5).

EDIT: I think I did not mention it yet, lightness shading (like Gouraud) is possible for aliased polygons. Here is a screenshot of testbgrafunc :
Title: Re: BGRABitmap tutorial
Post by: circular on May 01, 2011, 06:07:33 pm
Gintas, I've done a knob button component. See here:
http://www.lazarus.freepascal.org/index.php/topic,12411.msg67545.html

I know it's not a tutorial though.
Title: Re: BGRABitmap tutorial
Post by: circular on May 02, 2011, 04:12:42 pm
Hey people,

I've added SSE optimization for phong shading in BGRABitmap. It's used if available. It is twice faster with it. On my computer (win64), it works like a charm, but I don't know what happens on other systems.

I've also done some slight optimizations in usual blending operations and in resample.

It's available on subversion. I prefer waiting to have some feedbacks before publishing it as a zip file.
Title: Re: BGRABitmap tutorial
Post by: circular on May 03, 2011, 03:05:15 pm
Well having no reply, here is the last version of bgrabitmap (as a zip with bgrabitmap only):
http://sourceforge.net/projects/lazpaint/files/src/

This version can be connected to TAChart. See here :
http://www.lazarus.freepascal.org/index.php/topic,13023.msg67680.html
Title: Re: BGRABitmap tutorial
Post by: Gintas on May 04, 2011, 10:29:30 pm
I've done a knob button component.

*faint* Awesomeness! Thanks for the great job!
Title: Re: BGRABitmap tutorial
Post by: picstart on May 07, 2011, 02:48:46 am
The controls are great. Bgraknob is a very nice component that will install with few dependencies if any ( thanks circular). Now when it is included in bgracontrols ( button palette progressbar etc) dependencies show up .....It needs a 9.31 snapshot (that's fair enough since other components may have needed some bug fixes to work). However the other components are dependent on the 3.5 bgrabitmap and even then I couldn't get the palette icons in tab bgra controls to show for knob and progress bar.The panel speed button button etc display.
Title: Re: BGRABitmap tutorial
Post by: circular on May 07, 2011, 12:26:55 pm
*faint* Awesomeness! Thanks for the great job!
Thanks.

It needs a 9.31 snapshot (that's fair enough since other components may have needed some bug fixes to work). However the other components are dependent on the 3.5 bgrabitmap and even then I couldn't get the palette icons in tab bgra controls to show for knob and progress bar.The panel speed button button etc display.
9.31 is necessary for TBGRAImageList.

I don't know why you don't get the icons in the palette. When you open the BGRAControl packages, and you select units for these controls, does the icon show up at the bottom of the package window ?
Title: Re: BGRABitmap tutorial
Post by: picstart on May 07, 2011, 02:46:34 pm
I looked at the register code in the *.pas files They look fine. I'm using win32 XP pro.
Now when using the package installer the icons show for all but knob and progressbar and the lrs files are in the same location as button etc that do show when highlighted in the package installer. The controls are great but a great bottle of wine isn't that great if you can't get the cork out. Hopefully, I'm the only one that has trouble pouring the wine. Now I could get knob to install based on circular's earlier post ( under 9.30) it just wont show in the palette tabs with the combined package ( button panel speed button etc) under 9.31. Sure, many will use 9.31 snapshots as if they were the full release version but I'd prefer to stay with 9.30 the more stable version.. Is there a way to use 9.30 even if it meant a lesser featured bgracontrols package? So far I'm using knob since it has few dependencies so it runs with 9.30. After all 9.31 says use at your own risk so it comes with no suggestion of stability. I don't bet on odd numbers (9.31).
Title: Re: BGRABitmap tutorial
Post by: circular on May 07, 2011, 08:54:35 pm
I suppose you can compile the whole package except TBGRAImageList with version 0.9.30.

*********

New version of BGRABitmap (3.9) with :
- some optimisations (fillpoy, drawline, blur)
- multicolor gradient
- spline style (new parameter added to compute spline)

https://sourceforge.net/projects/lazpaint/files/src/

To use multicolor gradient, add BGRAGradientScanner in uses clause, then create a TBGRAMultiGradient object, and pass it as parameter to the gradients functions instead of the two colors.

About spline styles, you must add a new parameter, following values are accepted :
ssInside: draw the spline inside the polygon formed by the given points
ssCrossing: draw the spline inside and outside the polygon
ssOutside: draw outside
ssRoundOutside: draw outside and with bigger round curves
ssVertexToSide: draw a rounded polygon around the vertices

There is a new folder called bgraaggtest which contains tests that are very close to aggpas tests.
Title: Re: BGRABitmap tutorial
Post by: CaptBill on May 08, 2011, 12:13:14 am
Wow, awesome stuff. I fell like I am witnessing the ultimate graphics package really take shape in front of my eyes.

Everything I am going to need for 'me boat building application, before long!

Does BGRABitmap have a 'evaluate length' functionality for splines/beziers on the horizon? If I can evaluate length and compute normals (to a set point), I think that would be all I need to REALLY get rolling.

 Producing a beautifully curved 'proper' boat hull shape is no small task, yet I  believe BGRA is going to be the right tool for the task. The 2d stuff for sure and possibly the 3d too.

Excellent work, Sir.
Title: Re: BGRABitmap tutorial
Post by: circular on May 08, 2011, 01:11:04 pm
Thanks.

Well, I do not really understand what you mean by "on the horizon". To compute spline length, you can compute points and then compute the length of the polyline. Normals can also be computed from the polyline.

So in fact, functions that compute length and compute normals for polylines would be ok ? Or did you mean something else ?
Title: Re: BGRABitmap tutorial
Post by: lainz on May 09, 2011, 12:16:56 am
In testbgrafunc I see you added FPS. You can add a FPS limit? Like 'limit FPS to:' and an imput to set a value like '60'.
Title: Re: BGRABitmap tutorial
Post by: lainz on May 09, 2011, 04:41:10 am
I created an Inno Setup (jrsoftware.com) Script (.iss) to create a LazPaint setup (attached).

*Associate (with checkboxes) bmp, gif, ico, jpg, pcx, pdn, png files with LazPaint.

*Add LazPaint to 'Default Programs > Set your default programs' in Windows 7.
Title: Re: BGRABitmap tutorial
Post by: circular on May 09, 2011, 01:05:31 pm
Wow thanks. I've integrated into subversion.  :)
Title: Re: BGRABitmap tutorial
Post by: martinrame on May 09, 2011, 02:13:21 pm
Hi, I implemented a viewer for large images, that only shows on screen a viewport of the original images. It allow zooming and panning.

The app works ok, except for the centered zooming part.

Let me explain a little more how it works.

The original image can be, for example 4000x4000 pixels loaded into a TBGRAbitmap. Also I have a PictureBox in charge of showing an area of the original image, for example 800x400.

The panning is done by dragging the image, no scrollbars here. To do it, I have two variables, FLeft and FTop, that let me know what is the top-left point of the viewport.

When I do zooming, the original image is enlarged, but, as FLeft and FTop aren't moved, the image is expanded from that point. My problem is how can I accomplish zooming from the center of the PictureBox.

I did some calcs, that on paper looks correct, but on the application are wrong.

OriginalImg(4000,4000).  //width, height
ViewPort(0, 0, 800, 400). //x,y,width,height

After zooming (10%)
OriginalImage(4400, 4400);
// to center the image on the viewport I do this.
OriginalImageOffset = ((4400-4000) / 2)
ViewPortOffset = ((880 - 800) / 2)
FLeft = FLeft + (OriginalImageOffset - ViewPortOffset)
...
The same with FTop.

Could anyone tell me what I'm doing wrong?
Title: Re: BGRABitmap tutorial
Post by: Shebuka on May 09, 2011, 03:14:06 pm
After zooming (10%)
Code: Pascal  [Select][+][-]
  1. OriginalHeight := 4000;
  2. NewHeight := 4400;
  3. OriginalLeft := Fleft;
  4.  
  5. FLeft = OriginalLeft + (NewHeight - OriginalHeight) / 2;
Not tested, but must be this way.
Title: Re: BGRABitmap tutorial
Post by: martinrame on May 09, 2011, 03:50:04 pm
Thanks Shebuka, I tried your suggestion, but it doesn't work.

My code is this:

Code: [Select]
var
  lWidth: Integer;
  lHeight: Integer;
begin
  FTool:= tZoom;
  FZoom := FZoom * (0.1);

  // apply zoom to original image and get the new dimensions
  SetDicomZoom(FZoom);
  GetDimensions(FImgWidth, FImgHeight);

  lWidth := Round(PaintBox1.Width * FZoom);
  lHeight:= Round(PaintBox1.Height * FZoom);

  FLeft  := FLeft + ((lWidth- PaintBox1.Width) div 2);
  FTop  := FTop + ((lHeight- PaintBox1.Height) div 2);

  // Show the image on Paintbox.
  ShowDicomImage;
  PaintBox1.Invalidate;

Here is the image before zoom:
http://190.17.13.199/img/original-centered.png (http://190.17.13.199/img/original-centered.png)

And the image after zoom:
http://190.17.13.199/img/after-zoom.png (http://190.17.13.199/img/after-zoom.png)
Title: Re: BGRABitmap tutorial
Post by: Shebuka on May 09, 2011, 05:03:17 pm
what's not worked? i'v missed trunc and the sign of new coords (as well as var names XD )

Code: Pascal  [Select][+][-]
  1. OriginalHeight := FOriginImage.Height;
  2. OriginalWidth := FOriginImage.Width;
  3.  
  4. GetDimensions(NewWidth, NewHeight);
  5. //NewHeight := trunc(FOriginImage.Height * FZoom);   // or try this
  6. //NewWidth := trunc(FOriginImage.Width * FZoom);
  7.  
  8. OldTop := FTop;
  9. OldLeft := FLeft;
  10.  
  11. FTop = OldTop - trunc( (NewHeight - OriginalHeight) / 2 );
  12. FLeft = OldLeft - trunc( (NewWidth - OriginalWidth) / 2 );
try this way

edit: trunc
Title: Re: BGRABitmap tutorial
Post by: martinrame on May 09, 2011, 05:17:37 pm
Shebuka, I found the solution.

Code: [Select]
procedure TForm1.Zoom;
var
  lWidth: double;
  lHeight: double;
  lCenterX: double;
  lCenterY: double;
  lLeft: double;
  lTop: double;

begin
  // original image width and height
  lWidth := FImgWidth;
  lHeight := FImgHeight;

  // center point of PaintBox
  lCenterX := (PaintBox1.Width / 2);
  lCenterY := (PaintBox1.Height / 2);

  // original center of PaintBox plus offset
  lLeft:= FLeft + lCenterX + 1;
  lTop := FTop + lCenterY + 1;

  // apply zoom to original image and get new dimensions
  SetDicomZoom(FZoom);
  GetDimensions(FImgWidth, FImgHeight);

  // recalculate positions
  FLeft := (FImgWidth * lLeft / lWidth) - lCenterX - 1;
  FTop := (FImgHeight * lTop / lHeight) - lCenterY - 1;

  ShowDicomImage;
  PaintBox1.Invalidate;
end;
Title: Re: BGRABitmap tutorial
Post by: CaptBill on May 11, 2011, 06:45:33 am
Thanks.

Well, I do not really understand what you mean by "on the horizon". To compute spline length, you can compute points and then compute the length of the polyline. Normals can also be computed from the polyline.

So in fact, functions that compute length and compute normals for polylines would be ok ? Or did you mean something else ?

Sorry for the delay...Just back up from a nasty virus...No net for three days.

I am working with 'scales' upon a line/curve. So a line is made of line segments based on  ratios/divisions/scales. If I bend the strait line the ratios/segments need to be recomputed base on the new length, with the normals computed for each segment (perpendicular mainly) to the line.

These functions would work nice for making nice curvy forms and shaped buttons based on a bendable grid.
Title: Re: BGRABitmap tutorial
Post by: circular on May 11, 2011, 12:57:31 pm
Do you mean for example a line splitted into 3 parts, that you bend and the bent line has also 3 parts of the same ratio of length ?

This could be achieved with a object called for example TSpline, which is created with control points, and then methods like:
- PointAt(position:single) where position is in [0..1]
- NormalAt(position: single)
- GetPositionOf(point: TPointF): single that returns the position in[0..1] (well one possible position)
- GetPositionOfLength(length: single): single that returns the position so that [0..pos] has the wanted length
- Length:single -> full length
- ComputePoints(startPos,endPos: single) with position in [0..1]

So if you want to calcule three equal parts, you would do
Code: [Select]
  t1 := GetPositionOfLength( Length/3 );
  t2 := GetPositionOfLength( 2*Length/3 );
  part1 := ComputePoints(0,t1);
  part2 := ComputePoints(t1,t2);
  part3 := ComputePoints(t2,1);

Would it be allright?
Title: Re: BGRABitmap tutorial
Post by: lainz on May 11, 2011, 05:02:27 pm
Circular I can't open with LazPaint .bmp / .png files exported with GIMP with Alpha format

a8 r8 g8 b8 (alpha area is shown Black, visible area is shown transparent). > I can open those with XnView / GIMP. Pictures.zip > test.bmp

x8 r8 g8 b8 (alpha area is shown White, visible area is shown Black). > I can't open those with XnView / GIMP. Pictures.zip > test2.bmp

Related:
http://forums.adobe.com/thread/751592?tstart=1
http://1dollarsoftware.com/bmp.html (I attached all bitmaps by 'other applications' in bitmaps.zip)
Title: Re: BGRABitmap tutorial
Post by: CaptBill on May 11, 2011, 09:53:49 pm
Do you mean for example a line splitted into 3 parts, that you bend and the bent line has also 3 parts of the same ratio of length ?

This could be achieved with a object called for example TSpline, which is created with control points, and then methods like:
- PointAt(position:single) where position is in [0..1]
- NormalAt(position: single)
- GetPositionOf(point: TPointF): single that returns the position in[0..1] (well one possible position)
- GetPositionOfLength(length: single): single that returns the position so that [0..pos] has the wanted length
- Length:single -> full length
- ComputePoints(startPos,endPos: single) with position in [0..1]

So if you want to calcule three equal parts, you would do
Code: [Select]
  t1 := GetPositionOfLength( Length/3 );
  t2 := GetPositionOfLength( 2*Length/3 );
  part1 := ComputePoints(0,t1);
  part2 := ComputePoints(t1,t2);
  part3 := ComputePoints(t2,1);

Would it be allright?

That should work out very nice. I guess I missed those methods. Those should be the ones I need .Thanks.
Title: Re: BGRABitmap tutorial
Post by: circular on May 12, 2011, 04:57:58 am
@CaptBill:

These methods do not exist yet. I am talking about how we could design the object you need.
Title: Re: BGRABitmap tutorial
Post by: martinrame on May 13, 2011, 04:27:57 pm
Hi circular, I'm trying to move one method that uses TBGRABitmap to a CGI program (declaring LCLWidgetType to nogui), but I'm getting this error when I call that method:

Code: [Select]
TRasterImage.BitmapHandleNeeded: Unable to create handles, using default
[FORMS.PP] ExceptionOccurred
  Sender=EInvalidOperation
  Exception=Canvas does not allow drawing
  Stack trace:
  $00000000004E8E8B
  $0000000000516908
  $000000000065157C line 41 of ../../lazpaint/bgrabitmap/bgratext.pas
  $0000000000651606 line 46 of ../../lazpaint/bgrabitmap/bgratext.pas
  $000000000060A740 line 2410 of ../../lazpaint/bgrabitmap/bgradefaultbitmap.pas
  $0000000000602DC0 line 1313 of ../../lazpaint/bgrabitmap/bgradefaultbitmap.pas
  $00000000005FF69B line 650 of ../../lazpaint/bgrabitmap/bgradefaultbitmap.pas
  $00000000005FA912 line 145 of ../../lazpaint/bgrabitmap/bgrabitmap.pas
  $0000000000437056
TApplication.HandleException Canvas does not allow drawing
  Stack trace:
  $00000000004E8E8B
  $0000000000516908
  $000000000065157C line 41 of ../../lazpaint/bgrabitmap/bgratext.pas
  $0000000000651606 line 46 of ../../lazpaint/bgrabitmap/bgratext.pas
  $000000000060A740 line 2410 of ../../lazpaint/bgrabitmap/bgradefaultbitmap.pas
  $0000000000602DC0 line 1313 of ../../lazpaint/bgrabitmap/bgradefaultbitmap.pas
  $00000000005FF69B line 650 of ../../lazpaint/bgrabitmap/bgradefaultbitmap.pas
  $00000000005FA912 line 145 of ../../lazpaint/bgrabitmap/bgrabitmap.pas
  $0000000000437056
exception at 00000000004E8E8B:
Canvas does not allow drawing.

My method loads and image from a memory buffer to a TBGRABitmap, then I add some text to the image, then save the image as JPeg.

Do you know a way to do this in a CGI app?.

I've tried in the past using fpImage but it doesn't have ScanLine nor Canvas properties making it very difficult to use fonts in my bitmap.
Title: Re: BGRABitmap tutorial
Post by: CaptBill on May 13, 2011, 06:35:33 pm
@CaptBill:

These methods do not exist yet. I am talking about how we could design the object you need.

Excellent. I have been thinking about it and believe if your graphics can handle modeling boat hulls it can manage about anything. If we can solve a couple simple issues like these the rest should be easy. Like really nice shaped forms, skinning engines, layout designers etc. Think Rhino3d quality 'organic' look and quality. I am working out the grid based point selection process over here which I hope you will find useful as well.

Here is my current plan/ideas, as best I can describe:

  My idea is to be able to build a curve in two steps. Step 1: Draw curve on a rectangular grid ('scale' based grid). Step 2: using the normals, recompute the grid to conform to the curve. So what I have then is a curve with a 'scalar array grid' conforming to it. Then the idea is to set the scale to a 'thickness range' based on the wall thickness for the hull. Then I have pick the points for my inner wall, which now has a pre-configured 'range' of motions.

The grid is set up with 2 'scalar arrays', the arrays are populated with scale values, which now gives the array lots of 'qualities' that may not be obvious at first glance.  

The grid is a network of precomputed values (x,y, tone, color)based on scales, which is set up with , I call them, iterators.The idea is to have an iterator for each curve point. an origin, a scale value, and the endpoint. I merely set the iterators by simply picking from the indexed values of the scale. Plus, keep in mind that the scale values are carefully selected points, pre-engineered. The idea is to find the 'golden points' within a range vs. guessing by mouse. A good analogy for what i hope for is an array that you 'play like an instrument'.

(which, coincidentally,the perfect input device is a USB Synthesizer controller)

http://www.live-laptops.com/images/Novation-SL25-MKII-1.jpg (http://www.live-laptops.com/images/Novation-SL25-MKII-1.jpg)

I hope that gives you a better idea what I am thinking.

Thanks again.

Title: Re: BGRABitmap tutorial
Post by: circular on May 13, 2011, 10:14:20 pm
@martinrame:

I understand what you want to do. It would be possible to define a TBGRABitmap that works with no GUI by using some compiler directive. But the problem is that text functions are using available standard canvas to render the text. To avoid this, it would be necessary to load a true type file and render it with BGRA capabilities. By the way, this would be faster than what is currently implemented. But in this case, the program needs to have a ttf file to load.

Does it work if you don't use text functions ? If it is the case, your problem could be solved by adding true type capabilities to BGRABitmap. Maybe it could be possible to adapt aggpas code for true type files. Another approach would be to create bitmap fonts like in ZenGL, and then use PutImage to draw each char.
Title: Re: BGRABitmap tutorial
Post by: lainz on May 16, 2011, 04:28:44 pm
see some other comments from a blog

http://idkn.wordpress.com/2011/03/27/bgrabitmap/
Title: Re: BGRABitmap tutorial
Post by: freesailor on May 16, 2011, 05:44:23 pm
Hi I am developing a 3d engine and now work on shading (like phong, flat etc)
I was impressed with BGRABitmap which uses phong and I found in testbgrafunc project useful code related to 3d texturing with FillPolyPerspectiveMappingLightness, but didnt understand how it relates to phong shading.

In my project, i have some 3d objects and lights defined by their positions, and of course a camera object. and I want to use BGRABitmap to apply phong to these 3d objects  along with texturing.

Any help?
Title: Re: BGRABitmap tutorial
Post by: circular on May 16, 2011, 07:03:16 pm
@freesailor:

Until now, Phong shading is only implemented for drawing with a height map (TPhongShading in BGRAGradients). You can choose one light, with one position and one color.

With texture mapping, there is only linear lighting. You can fill polygons with some gouraud lighting by giving lighting for each vertex. There is no light color here.

I suppose it would be possible to develop some mix of FillPoly and TPhongShading. In bgrapolygonaliased.pas there are procedures that fill aliased polygons with texture and lighting. You can derive one of these procedures to add phong shading in it. But the TPhongShading class is very specific, so you can only inspire from it to make your own phong code.

In the meantime, you can just use gouraud lighting. To do so, you need to compute the light for each vertex. The normal of each vertex is the mean of the normals of the surfaces around it. Then with a scalar product with all lights, you can have the resulting lighting. Put it in the interval 0..65535 (where 32768 is neutral) and then call FillPolyPerspectiveMappingLightness.

Anyway, Phong shading with texture mapping will be much slower. This is software rendering.
Title: Re: BGRABitmap tutorial
Post by: tomek on June 08, 2011, 10:22:37 pm
Hi,
I just start with BGRABitmap and I've question.
Is there any way to fill polygon with gradient ?
Title: Re: BGRABitmap tutorial
Post by: circular on June 09, 2011, 12:10:15 pm
Yes, to do this, use BGRAGradientScanner unit, create a TBGRAGradientScanner object, and pass it as a parameter to the FillPoly function.
Title: Re: BGRABitmap tutorial
Post by: tomek on June 11, 2011, 07:43:11 pm
Yes, to do this, use BGRAGradientScanner unit, create a TBGRAGradientScanner object, and pass it as a parameter to the FillPoly function.


thx, I'm impressed with the job you did  8)
Title: Re: BGRABitmap tutorial
Post by: tomek on June 11, 2011, 10:09:42 pm
One more thing. I use BGRABitmap in most with TAChart, and I see one problem with fonts.
Simplest way to reproduce:
Open TAChart demo - "bgra" and change YMax to 1 in RandomChartSource1

I attached screen. On labels 0,1 ... 0,7 you will see one extra pixel on the center of label it seams like semicolon not comma ;)

I don't know is this problem with TAChart or BGRA because with BGRA everything is ok:
Code: [Select]
 
image: TBGRABitmap;
image.FontHeight := 30;
image.FontAntialias := true;
image.TextOut(1,1,'0,1,2,3,4',clBlack);
Title: Re: BGRABitmap tutorial
Post by: Ask on June 13, 2011, 03:41:46 am
I don't know is this problem with TAChart or BGRA because with BGRA everything is ok:

It turned out to be due to slight incompatibility in BGRABtimap vs TCanvas line drawing,
should be fixed in r31189.

Code: [Select]
 
image.FontAntialias := true;

I did not notice BGRA has font antialiasing. Since r31190 you can use it in TAChart
by setting AntialiasingMode to amOn (see updated demo).

By the way, circular, is there any way to globally turn antialiasing on/off in BGRABitmap?
It would allow me to fully implement AntialiasingMode similar to other back-ends.

Title: Re: BGRABitmap tutorial
Post by: CaptBill on June 13, 2011, 04:27:28 am
This code worked fine on Windows7 but won't compile under Linux.
Tried many ways to cast the variables to the procedure. Nothing seems to work. Keeps calling the scanner version of DrawLineAntialias but I want the pbgrapixel version of the overloaded procedure.

error"Got PBgraPixel expected PBgraScanner"
(fpc2.4.2 , svn laz i386-linux-gtk2 under Debian4 distro)

Would also be great if you could do a tutorial of the TBgraCustomScanner functionality.

Thanks

Quote
procedure paintlines(XLines,YLines:tarray;Xlength,YLength:double; imagebox:TImage);
var
    p: PBGRAPixel;
    image: TBGRABitmap;
    hsla: THSLAPixel;
    iX,iY :integer;
      xl,yl,intXLength,intYLength:integer;

begin
  image := TBGRABitmap.Create(imagebox.width,imagebox.height);
  hsla.lightness := 32768;
  hsla.alpha := 65535;

  for iX:= 0 to length(XLines) do
  begin

    xl:=round(XLines[ix]);
    yl:=round(YLines[iy]);
    IntXLength:= round(XLength);
    IntYLength:= round(YLength);

  image.DrawLineAntialias(xl,0,xl+IntXLength,0,p,1);    ///error"Got PBgraPixel expected PBgraScanner"       

  for iY:= 0 to length(YLines) do
  begin
  //image.DrawHorizLine(0,round(YLines[iy]),round(YLines[iy]+YLength,p));
  end;

  image.InvalidateBitmap;

  image.Draw(imagebox.Canvas,0,0,True);
  image.free;
 end;
Title: Re: BGRABitmap tutorial
Post by: JD on June 13, 2011, 10:55:53 am
Sorry but I'm a little out of date with this. Can we now draw charts (TAChart) using BGRABitmap?
Title: Re: BGRABitmap tutorial
Post by: Ask on June 13, 2011, 12:44:57 pm
Yes, see bgra demo in the TAChart directory.
Title: Re: BGRABitmap tutorial
Post by: tomek on June 13, 2011, 12:47:38 pm
It turned out to be due to slight incompatibility in BGRABtimap vs TCanvas line drawing,
should be fixed in r31189.

Thanks Ask, works fine now.

@JD, yes TAChart can use BGRA, but not all charts are done, as example Pie Chart not.
BTW @Ask, can this be done soon ? I see that RadialPie function exists in BGRACanvas, it would be cool.
Title: Re: BGRABitmap tutorial
Post by: Ask on June 13, 2011, 02:04:47 pm
See r31199.
Title: Re: BGRABitmap tutorial
Post by: circular on June 13, 2011, 04:02:58 pm
By the way, circular, is there any way to globally turn antialiasing on/off in BGRABitmap?
It would allow me to fully implement AntialiasingMode similar to other back-ends.
You mean in CanvasBGRA ? You can do it with Font.Antialiasing. You can use it in chart back-end.

Font antialising must be explicitely set because it is slower and not always very readable. Personnaly I would not use it in TAChart axes.

This code worked fine on Windows7 but won't compile under Linux.
Tried many ways to cast the variables to the procedure. Nothing seems to work. Keeps calling the scanner version of DrawLineAntialias but I want the pbgrapixel version of the overloaded procedure.
You cannot call it with a pbgrapixel but with a TBGRAPixel. If you have a PBRAPixel, you can dereference it with ^. But I don't understand you're code. You don't seem to use the hsla variable.
Title: Re: BGRABitmap tutorial
Post by: CaptBill on June 13, 2011, 05:36:04 pm
Thanks Circular,

Didn't even notice the wrong variable assignment. So I was calling the pointer version.... (P) .

Man,should have seen that.

..also about the demo request for TBgraCustomScanner. I completely forgot about the demo app in Lazpaint directory. The plasma/fire demo should be all anyone needs to see the scanner functions at work.

....also the answer to the question I had about getting the length/normals of a bezier (about a week ago) I found right on the Wiki demo staring me in the face....all the points(technically lines) are in the return array of ComputeSpline/Bezier functions....just might need to modify the array to send floats instead of integers is all.

Thanks again for everything.

Title: Re: BGRABitmap tutorial
Post by: Ask on June 13, 2011, 10:42:38 pm
By the way, circular, is there any way to globally turn antialiasing on/off in BGRABitmap?
It would allow me to fully implement AntialiasingMode similar to other back-ends.
You mean in CanvasBGRA ? You can do it with Font.Antialiasing. You can use it in chart back-end.
Yes, I already did that. The question was about global antialiasing, referring to all drawing,
not just fonts.

Font antialising must be explicitely set because it is slower and not always very readable. Personnaly I would not use it in TAChart axes.
I agree, it is off by default in TAChart.
Title: Re: BGRABitmap tutorial
Post by: circular on June 14, 2011, 06:09:54 pm
..also about the demo request for TBgraCustomScanner. I completely forgot about the demo app in Lazpaint directory. The plasma/fire demo should be all anyone needs to see the scanner functions at work.
Oops I forget to answer about TBGRACustomScanner. There is an example here:

http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_11
(TBGRAMultiplyScanner example)

Quote
....also the answer to the question I had about getting the length/normals of a bezier (about a week ago) I found right on the Wiki demo staring me in the face....all the points(technically lines) are in the return array of ComputeSpline/Bezier functions....just might need to modify the array to send floats instead of integers is all.
ComputeSpline returns an array of PointF so it's alread floats. But the precision may not be sufficient. It depends on what you need.

12390.msg70553#msg70553 date=1307997758]
Yes, I already did that. The question was about global antialiasing, referring to all drawing,
not just fonts.
[/quote]
Well there is CanvasBGRA.AntialiasingMode. Is that what you were looking for?
Title: Re: BGRABitmap tutorial
Post by: Ask on June 14, 2011, 10:28:23 pm
Quote
Well there is CanvasBGRA.AntialiasingMode. Is that what you were looking for?

Basically, yes. It is, however, only available from TBGRACanvas, not TBGRABitmap.
Should I convert TAChart to using TBGRACanvas?
Title: Re: BGRABitmap tutorial
Post by: circular on June 14, 2011, 10:40:04 pm
You don't need to do it, i've already done it here :
http://www.lazarus.freepascal.org/index.php/topic,13023.0.html
Title: Re: BGRABitmap tutorial
Post by: Ask on June 15, 2011, 05:51:02 am
Ah! I indeed you did.
I have asked you about differences with tachart implementation,
this is the most important difference. After noticing it, I see the point of your version.
Now I have few questions:
1) Do you ever plan to produce a version of BGRABitmap which does not depend on LCL?
  I have taken great care to avoid this dependency in TAChart back-ends, so they can
  be used in applications such as web servers and games.
  If yo do not plan this, adding LCL dependency to bgra back-end is ok,
  otherwise I would like to work around it.
2) From architectural POV, I thought that BGRABitmap is the main fully functional API,
  and BGRACanvas is just an adaptor that exposes part of functionality in
  TCanvas-compatible manner. However, BGRACanvas now has functionality
  (AntiliasingMode) not present in BGRABitmap, which violates the above principle.
3) What is the reason for check
  if (FCanvas.Pen.ActualWidth = 1) and (FCanvas.Pen.Style = psDot) then
  in LineTo procedure?
Title: Re: BGRABitmap tutorial
Post by: circular on June 15, 2011, 01:02:58 pm
1) Do you ever plan to produce a version of BGRABitmap which does not depend on LCL?
No. But if someone wants to do it that's ok.

Quote
2) From architectural POV, I thought that BGRABitmap is the main fully functional API,
  and BGRACanvas is just an adaptor that exposes part of functionality in
  TCanvas-compatible manner. However, BGRACanvas now has functionality
  (AntiliasingMode) not present in BGRABitmap, which violates the above principle.
No. For example you can call FillPoly or FillPolyAntialias.

Quote
3) What is the reason for check
  if (FCanvas.Pen.ActualWidth = 1) and (FCanvas.Pen.Style = psDot) then
  in LineTo procedure?
It's to call a faster procedure (pixel line) instead of the generic one (polygon line). These lines are widely used in TAChart for the grids. As they are horizontal and vertical, there is no point in using the nice rendering.
Title: Re: BGRABitmap tutorial
Post by: circular on June 15, 2011, 10:40:21 pm
Hello people !

I've added a Canvas2D property, which can be used to draw like on the HTML Canvas element.

http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_14

It's not finished yet, some functions are not available, but you can already do some stuff.
Title: Re: BGRABitmap tutorial
Post by: Ask on June 16, 2011, 08:08:54 am
1) Do you ever plan to produce a version of BGRABitmap which does not depend on LCL?
No. But if someone wants to do it that's ok.
Sure, but moving TAChart to BGRACanvas will make that task harder.
Anyway, since such a change does not look likely, I will do the move.

Quote
BGRACanvas now has functionality
  (AntiliasingMode) not present in BGRABitmap, which violates the above principle.
No. For example you can call FillPoly or FillPolyAntialias.
But using BGRABitmap you can not switch antialiasing on and off without changing code.
(Or wrapping every call into a conditional statement, of course).

Last question: what is your name? I would like to credit you in the commit message.

Title: Re: BGRABitmap tutorial
Post by: circular on June 16, 2011, 12:17:15 pm
1) Do you ever plan to produce a version of BGRABitmap which does not depend on LCL?
No. But if someone wants to do it that's ok.
Sure, but moving TAChart to BGRACanvas will make that task harder.
Anyway, since such a change does not look likely, I will do the move.
You don't need to do that. You just need to use an appropriate back-end with new functions for drawing
adjacent polygons or phong effects. You can add some fallback behavior in the generic class.

What about assigning a back-end to the TAChart object, so that it uses any back-end,
without any dependency ?

Quote
But using BGRABitmap you can not switch antialiasing on and off without changing code.
(Or wrapping every call into a conditional statement, of course).
That's just another way.

Quote
Last question: what is your name? I would like to credit you in the commit message.
Well, circular, or circular17 if you prefer.
Title: Re: BGRABitmap tutorial
Post by: Ask on June 16, 2011, 12:29:25 pm
Quote
You don't need to do that. You just need to use an appropriate back-end with new functions for drawing
adjacent polygons or phong effects. You can add some fallback behavior in the generic class.
Of course, I did not mean converting all TAChart, just BGRA back-end.
As for new back-end functions: I understand what do you mean by phong effects,
but what are "adjacent polygons"?

Quote
What about assigning a back-end to the TAChart object, so that it uses any back-end,
without any dependency ?
It already works this way.
However, if we are speaking of LCL dependency, we have to consider entire application.
For example, there are people who want to use TAChart in web-server code.
It is now possible, although not quite efficient, by using fpcanvas back-end
and nogui widgetset. I plan to further reduce LCL dependencies
to avoid the need for widgetset at all.
Unfortunately, fpcanvas is slightly limited in functionality,
so I'd like to have other LCL-indepenent back-ends.
Title: Re: BGRABitmap tutorial
Post by: circular on June 16, 2011, 01:22:23 pm
Unfortunately, fpcanvas is slightly limited in functionality,
so I'd like to have other LCL-indepenent back-ends.
Now I understand your need. aggpas does not work already for this?
Title: Re: BGRABitmap tutorial
Post by: Ask on June 16, 2011, 01:30:11 pm
It almost does -- basic AggPas is independent from LCL,
but it has an adaptor (LCLAggPas, similar to BGRACanvas) which I used.
I wanted to convert aggpas back-end to use AggPas directly,
but hit some issues, and since nobody maintains AggPas, they are still unresolved.
Title: Re: BGRABitmap tutorial
Post by: circular on June 16, 2011, 05:05:51 pm
Problem is BGRABitmap is deeply linked to TBitmap. It is on purpose, to allow easy switching between TBGRABitmap and LCL bitmaps. As a matter of fact, optimized versions use internally operating system bitmaps (DIB section on Windows and same thing on Linux).

Maybe it could be possible to do a no-widgetset version with compiler directives by defining a fake type for TBitmap (could be some FPImage type) and equivalents for all other types.

But I don't understand why you need this. It is possible to do a server-side application with LCL. You can draw using LCL and save it into a stream to send to the client-side.
Title: Re: BGRABitmap tutorial
Post by: Ask on June 17, 2011, 01:47:28 am
Quote
Problem is BGRABitmap is deeply linked to TBitmap. It is on purpose, to allow easy switching between TBGRABitmap and LCL bitmaps. As a matter of fact, optimized versions use internally operating system bitmaps (DIB section on Windows and same thing on Linux).

I know, and that is ok. The idea is that if BGRABitmap *API* would not depend on LCL,
you could create a variant which does not require LCL in implementation either.
Note that, precisely speaking, there are widgetset-independent parts in LCL too,
so, for example, it is ok to use GraphTypes unit, but not Graphics.
The fact that TPen/TBrush/TColor etc. are defined in the latter instead of the former
is IMO a design deficiency of LCL, but it is not easy to fix due to compatibility requirements.

Quote
It is possible to do a server-side application with LCL.
That was my first reaction too. As I said, LCL design has some problems.
You can look at this thread for relevant discussion:
http://www.mail-archive.com/lazarus@lists.lazarus.freepascal.org/msg18414.html (http://www.mail-archive.com/lazarus@lists.lazarus.freepascal.org/msg18414.html)
Title: Re: BGRABitmap tutorial
Post by: lainz on June 17, 2011, 04:23:54 am
Hello people !

I've added a Canvas2D property, which can be used to draw like on the HTML Canvas element.

http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_14

It's not finished yet, some functions are not available, but you can already do some stuff.

Now we can do the "Paw" for the lazarus about dialog in a easy way:
http://wiki.lazarus.freepascal.org/Sample_Graphics#Lazarus_About

This is an online converter from SVG to Canvas:
* http://www.professorcloud.com/svg-to-canvas/

Paw.svg:
Code: Pascal  [Select][+][-]
  1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2. <!-- Created with Inkscape (http://www.inkscape.org/) -->
  3.  
  4. <svg
  5.    xmlns:dc="http://purl.org/dc/elements/1.1/"
  6.    xmlns:cc="http://creativecommons.org/ns#"
  7.    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  8.    xmlns:svg="http://www.w3.org/2000/svg"
  9.    xmlns="http://www.w3.org/2000/svg"
  10.    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  11.    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  12.    width="210mm"
  13.    height="297mm"
  14.    id="svg2"
  15.    version="1.1"
  16.    inkscape:version="0.48.1 "
  17.    sodipodi:docname="Documento nuevo 1">
  18.   <defs
  19.      id="defs4" />
  20.   <sodipodi:namedview
  21.      id="base"
  22.      pagecolor="#ffffff"
  23.      bordercolor="#666666"
  24.      borderopacity="1.0"
  25.      inkscape:pageopacity="0.0"
  26.      inkscape:pageshadow="2"
  27.      inkscape:zoom="1.4"
  28.      inkscape:cx="9.3913571"
  29.      inkscape:cy="912.34676"
  30.      inkscape:document-units="px"
  31.      inkscape:current-layer="layer1"
  32.      showgrid="false"
  33.      inkscape:window-width="1920"
  34.      inkscape:window-height="991"
  35.      inkscape:window-x="-11"
  36.      inkscape:window-y="-11"
  37.      inkscape:window-maximized="1" />
  38.   <metadata
  39.      id="metadata7">
  40.     <rdf:RDF>
  41.       <cc:Work
  42.          rdf:about="">
  43.         <dc:format>image/svg+xml</dc:format>
  44.         <dc:type
  45.            rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  46.         <dc:title></dc:title>
  47.       </cc:Work>
  48.     </rdf:RDF>
  49.   </metadata>
  50.   <g
  51.      inkscape:label="Capa 1"
  52.      inkscape:groupmode="layer"
  53.      id="layer1">
  54.     <path
  55.        style="fill:#3f5e99;fill-opacity:1;stroke:none"
  56.        d="m 89.724698,11.312043 c 5.80161,3.182532 10.798522,7.526765 13.026742,13.654369 11.49434,1.620435 20.31928,18.043716 15.96682,29.538252 -3.94021,10.405809 -25.292162,13.596789 -29.716822,4.747459 -2.76962,-5.539228 1.87646,-11.039014 -0.14794,-17.112216 -1.45209,-4.356264 -6.64545,-8.265788 -3.25761,-15.04147 1.47597,-2.951955 9.17033,-1.818889 9.26777,-3.654369 0.20307,-3.825233 -2.21478,-5.278664 -4.64183,-8.117602 z"
  57.        id="path3768"
  58.        inkscape:connector-curvature="0"
  59.        sodipodi:nodetypes="ccssssscc" />
  60.     <path
  61.        sodipodi:nodetypes="ccssssscc"
  62.        inkscape:connector-curvature="0"
  63.        id="path3770"
  64.        d="m 53.024288,20.876975 c -2.89533,5.950144 -4.46258,12.383277 -2.73968,18.671687 -8.44388,7.965335 -6.15429,26.468341 4.04073,33.333471 9.22937,6.21487 28.49858,-3.52094 26.99519,-13.2999 -0.94103,-6.121132 -7.91112,-7.924322 -9.76892,-14.050545 -1.33259,-4.394294 0.64621,-10.586201 -6.03442,-14.157811 -2.91055,-1.556044 -8.53498,3.815435 -9.67528,2.373838 -2.37643,-3.004361 -1.24324,-5.587834 -0.90326,-9.307317 z"
  65.        style="fill:#3f5e99;fill-opacity:1;stroke:none" />
  66.     <path
  67.        style="fill:#3f5e99;fill-opacity:1;stroke:none"
  68.        d="m 16.284108,78.650993 c 0.33183,6.60887 2.06006,13.00063 6.6011,17.67946 -3.55788,11.049297 7.36817,26.156417 19.60985,27.256217 11.08218,0.99562 23.27085,-16.8236 17.23938,-24.666407 -3.77539,-4.9092 -10.75134,-3.12881 -15.33238,-7.60051 -3.28595,-3.20752 -4.53732,-9.58635 -12.11221,-9.49487 -3.30014,0.0399 -5.63831,7.45741 -7.33233,6.74412 -3.53041,-1.48654 -3.78306,-4.29628 -5.27831,-7.7189 z"
  69.        id="path3772"
  70.        inkscape:connector-curvature="0"
  71.        sodipodi:nodetypes="ccssssscc" />
  72.     <path
  73.        sodipodi:nodetypes="ccssssscc"
  74.        inkscape:connector-curvature="0"
  75.        id="path3774"
  76.        d="m 152.77652,37.616125 c 3.90882,5.339314 6.59682,11.390439 6.02149,17.885168 9.72759,6.33402 10.77019,24.94899 1.96094,33.52017 -7.97486,7.75936 -28.67001,1.61128 -28.93241,-8.2791 -0.16424,-6.19086 6.37322,-9.20667 7.11017,-15.56583 0.52861,-4.56137 -2.5214,-10.301831 3.41628,-15.006226 2.58686,-2.049564 9.07808,2.234256 9.94337,0.612609 1.80333,-3.379591 0.22811,-5.719921 -0.76891,-9.319379 z"
  77.        style="fill:#3f5e99;fill-opacity:1;stroke:none" />
  78.     <path
  79.        style="fill:#3f5e99;fill-opacity:1;stroke:none"
  80.        d="m 139.65359,109.38478 c 39.48146,14.41504 2.85939,36.93 -20.45559,42.17386 -23.314982,5.24386 -77.260092,6.26452 -43.689092,-28.53681 3.47117,-3.59838 4.10895,-18.82451 6.56599,-23.738577 4.28626,-5.95359 24.160382,-12.37517 31.062192,-10.35406 15.09376,5.03125 12.83007,17.967137 26.5165,20.455587 z"
  81.        id="path3778"
  82.        inkscape:connector-curvature="0"
  83.        sodipodi:nodetypes="czsccc" />
  84.   </g>
  85. </svg>

Here is the Paw converted from my paw.svg

Circular you can put the below code in the Wiki example?

Code: Pascal  [Select][+][-]
  1. var draw = function(ctx) {
  2. ctx.save();
  3. ctx.beginPath();
  4. ctx.moveTo(0,0);
  5. ctx.lineTo(793.7007874015749,0);
  6. ctx.lineTo(793.7007874015749,1122.5196850393702);
  7. ctx.lineTo(0,1122.5196850393702);
  8. ctx.closePath();
  9. ctx.clip();
  10. ctx.strokeStyle = 'rgba(0,0,0,0)';
  11. ctx.lineCap = 'butt';
  12. ctx.lineJoin = 'miter';
  13. ctx.miterLimit = 4;
  14. ctx.save();
  15. ctx.restore();
  16. ctx.save();
  17. ctx.restore();
  18. ctx.save();
  19. ctx.save();
  20. ctx.fillStyle = "#3f5e99";
  21. ctx.strokeStyle = "rgba(0, 0, 0, 0.0)";
  22. ctx.beginPath();
  23. ctx.moveTo(89.724698,11.312043);
  24. ctx.bezierCurveTo(95.526308,14.494575,100.52322000000001,18.838808,102.75144,24.966412);
  25. ctx.bezierCurveTo(114.24578,26.586847,123.07072,43.010127999999995,118.71826,54.504664);
  26. ctx.bezierCurveTo(114.77805000000001,64.910473,93.426098,68.10145299999999,89.00143800000001,59.252123);
  27. ctx.bezierCurveTo(86.231818,53.712894999999996,90.877898,48.213108999999996,88.853498,42.139906999999994);
  28. ctx.bezierCurveTo(87.401408,37.78364299999999,82.208048,33.87411899999999,85.595888,27.098436999999993);
  29. ctx.bezierCurveTo(87.071858,24.146481999999992,94.76621800000001,25.279547999999995,94.863658,23.444067999999994);
  30. ctx.bezierCurveTo(95.066728,19.618834999999994,92.648878,18.165403999999995,90.221828,15.326465999999995);
  31. ctx.closePath();
  32. ctx.fill();
  33. ctx.stroke();
  34. ctx.restore();
  35. ctx.save();
  36. ctx.fillStyle = "#3f5e99";
  37. ctx.strokeStyle = "rgba(0, 0, 0, 0.0)";
  38. ctx.beginPath();
  39. ctx.moveTo(53.024288,20.876975);
  40. ctx.bezierCurveTo(50.128958,26.827119000000003,48.561707999999996,33.260252,50.284608,39.548662);
  41. ctx.bezierCurveTo(41.840728,47.513997,44.130318,66.017003,54.325338,72.88213300000001);
  42. ctx.bezierCurveTo(63.554708000000005,79.09700300000002,82.823918,69.36119300000001,81.320528,59.58223300000001);
  43. ctx.bezierCurveTo(80.379498,53.461101000000006,73.409408,51.65791100000001,71.551608,45.53168800000001);
  44. ctx.bezierCurveTo(70.219018,41.13739400000001,72.197818,34.94548700000001,65.517188,31.373877000000007);
  45. ctx.bezierCurveTo(62.606638000000004,29.817833000000007,56.98220800000001,35.18931200000001,55.841908000000004,33.74771500000001);
  46. ctx.bezierCurveTo(53.465478000000004,30.743354000000007,54.598668,28.159881000000006,54.938648,24.44039800000001);
  47. ctx.closePath();
  48. ctx.fill();
  49. ctx.stroke();
  50. ctx.restore();
  51. ctx.save();
  52. ctx.fillStyle = "#3f5e99";
  53. ctx.strokeStyle = "rgba(0, 0, 0, 0.0)";
  54. ctx.beginPath();
  55. ctx.moveTo(16.284108,78.650993);
  56. ctx.bezierCurveTo(16.615938,85.259863,18.344168,91.651623,22.885208,96.330453);
  57. ctx.bezierCurveTo(19.327327999999998,107.37975,30.253377999999998,122.48687000000001,42.495058,123.58667);
  58. ctx.bezierCurveTo(53.577238,124.58229,65.765908,106.76307,59.734438,98.920263);
  59. ctx.bezierCurveTo(55.959047999999996,94.01106300000001,48.983098,95.791453,44.402058,91.319753);
  60. ctx.bezierCurveTo(41.116108,88.112233,39.864737999999996,81.73340300000001,32.289848,81.824883);
  61. ctx.bezierCurveTo(28.989708,81.864783,26.651538,89.282293,24.957518,88.569003);
  62. ctx.bezierCurveTo(21.427108,87.08246299999999,21.174458,84.272723,19.679208,80.85010299999999);
  63. ctx.closePath();
  64. ctx.fill();
  65. ctx.stroke();
  66. ctx.restore();
  67. ctx.save();
  68. ctx.fillStyle = "#3f5e99";
  69. ctx.strokeStyle = "rgba(0, 0, 0, 0.0)";
  70. ctx.beginPath();
  71. ctx.moveTo(152.77652,37.616125);
  72. ctx.bezierCurveTo(156.68534,42.955439,159.37334,49.006564,158.79801,55.501293);
  73. ctx.bezierCurveTo(168.5256,61.835313,169.5682,80.450283,160.75895,89.021463);
  74. ctx.bezierCurveTo(152.78409,96.780823,132.08894,90.63274299999999,131.82654,80.742363);
  75. ctx.bezierCurveTo(131.6623,74.551503,138.19976,71.535693,138.93671,65.17653299999999);
  76. ctx.bezierCurveTo(139.46532,60.615162999999995,136.41531,54.87470199999999,142.35299,50.170306999999994);
  77. ctx.bezierCurveTo(144.93985,48.12074299999999,151.43107,52.404562999999996,152.29636,50.78291599999999);
  78. ctx.bezierCurveTo(154.09968999999998,47.403324999999995,152.52446999999998,45.062994999999994,151.52745,41.463536999999995);
  79. ctx.closePath();
  80. ctx.fill();
  81. ctx.stroke();
  82. ctx.restore();
  83. ctx.save();
  84. ctx.fillStyle = "#3f5e99";
  85. ctx.strokeStyle = "rgba(0, 0, 0, 0.0)";
  86. ctx.beginPath();
  87. ctx.moveTo(139.65359,109.38478);
  88. ctx.bezierCurveTo(179.13505,123.79982000000001,142.51298,146.31478,119.19800000000001,151.55864);
  89. ctx.bezierCurveTo(95.883018,156.8025,41.93790800000001,157.82316,75.508908,123.02183);
  90. ctx.bezierCurveTo(78.980078,119.42344999999999,79.61785800000001,104.19731999999999,82.074898,99.283253);
  91. ctx.bezierCurveTo(86.361158,93.329663,106.23528,86.908083,113.13709,88.929193);
  92. ctx.bezierCurveTo(128.23085,93.960443,125.96716,106.89633,139.65359,109.38478);
  93. ctx.closePath();
  94. ctx.fill();
  95. ctx.stroke();
  96. ctx.restore();
  97. ctx.restore();
  98. ctx.restore();
  99. };
Title: Re: BGRABitmap tutorial
Post by: circular on June 17, 2011, 12:13:37 pm
Thanks Lainz. I've updated the sample graphics page.
Title: Re: BGRABitmap tutorial
Post by: lainz on June 17, 2011, 06:14:14 pm
Thanks Lainz. I've updated the sample graphics page.

Amazing!
Title: Re: BGRABitmap tutorial
Post by: circular on June 17, 2011, 07:28:58 pm
I would not have believed it either... Thanks for converting from SVG !
Title: Re: BGRABitmap tutorial
Post by: lainz on June 17, 2011, 07:33:15 pm
I would not have believed it either... Thanks for converting from SVG !

I just draw the SVG. The conversion is thanks to the Professor Cloud SVG-To-Canvas online converter!
Title: Re: BGRABitmap tutorial
Post by: circular on June 18, 2011, 10:25:45 pm
I've added some functionalities to Canvas2D :
- save/restore fillstyle strokestyle etc.
- isPointInPath function
- arcTo function
- arcs can be transformed now
- can toggle pixel-centered coordinates (default behavior of HTML canvas is non centered)

In testcanvas2d, added paw example, shearing of arcs and mouse highlight for triangles and paw.
Title: Re: BGRABitmap tutorial
Post by: lainz on June 19, 2011, 12:37:39 am
mouse highlight for triangles and paw.

With this I can do sizable buttons with very customized shapes.
Title: Re: BGRABitmap tutorial
Post by: circular on June 19, 2011, 03:46:50 pm
would be cool to have kind of vectorial buttons.

I've updated canvas2D with other features :
- join miter limit value
- linear gradient
- pattern (repeat-x or y or both or none)

By the way I added to BGRABitmap :
- JoinMiterLimit property
- repeat x or y for bitmap scanners (TBGRABitmapScanner and TBGRAffineBitmapTransform in BGRATransform unit)
- getPixelCycle with repeat x or y

What is not done yet with Canvas2D :
  globalCompositeOperation
  createRadialGradient
  shadow functions (done)
  clipping (done)
  text functions
  drawImage(in image, in double sx, in double sy, in double sw, in double sh, in double dx, in double dy, in double dw, in double dh)
  image data functions

-> globalCompositeOperation and clipping (done) would need some work on basic BGRABitmap drawing capabilities
-> createRadialGradient : I don't know how to do this (it's not just a radial gradient in fact but a conic gradient with two centers and two radii)
-> shadowFunctions : it suppose it's not too complicated to do (done)
-> text functions : would need vectorial fonts
-> drawImage : this case just gives me a headache
-> image data functions : well, it's not so useful because it's already available with standard BGRABitmap
Title: Re: BGRABitmap tutorial
Post by: circular on June 20, 2011, 11:30:40 am
Hey people. I've added clipping, lineStyle, and opacity for bitmaps. Here is a screenshot :

Added : spline,roundRect,clearPath

These are not defined in the HTML canvas reference but can be useful.
Title: Re: BGRABitmap tutorial
Post by: tomek on June 21, 2011, 03:41:23 pm
One question:
I try to create round border (without fill):
    RoundRectAntialias(ARect.Left,ARect.Top,ARect.Right,ARect.Bottom, 5 , 5 , ColorToBGRA(clBlack) , 2 , []);
but I want to have psDot, psDash, .... "pen styles". I see that RectAntialias can use only brushStyles, gradients, etc.

Is there any proc. to draw Round Rect (as ex. RoundRectBorderAntialias(0,0,10,10, 5, 5) ) with Pen (and pen styles) ?

RESOLVED!! - I found "ComputeRoundRect"  + DrawPolyLineAntialias   8)
Title: Re: BGRABitmap tutorial
Post by: circular on June 22, 2011, 07:37:15 pm
Yes. That's a way to do it. I guess I should do something about it... There is this issue with round rectangles and with ellipses.

...

Done. Now the pen style is taken into account for round rectangles and ellipses (on subversion).
Title: Re: BGRABitmap tutorial
Post by: tomek on June 23, 2011, 01:23:40 pm
Great ;)
another question about phong (BGRAGradients unit). Can phong use Transparency with main color (ex. BC1.alpha:=100) ?
This is sample code (I can't get transparency) :
Code: [Select]
procedure TForm1.FormPaint(Sender: TObject);
var
  bmp    : TBGRABitmap;
  phong  : TPhongShading;
  BC1    : TBGRAPixel;
begin
  bmp := TBGRABitmap.Create(ClientWidth, ClientHeight, BGRAWhite);
  bmp.DrawHorizLine(0,120,ClientWidth,BGRABlack);
  phong := TPhongShading.Create;
  phong.LightColor:=BGRAWhite;
  BC1:=ColorToBGRA(clRed);
  BC1.alpha:=100; 
  phong.DrawRectangle(bmp,Rect(50,50,200,200),10,10,BC1,true,[]);
  bmp.Draw(Canvas, 0, 0, True);
  bmp.Free;
end; 

-------------------------------------------
Edit:
I try to do something with this, in file phongdraw.inc in "function ComputePixel" I add:
Code: [Select]
    Alpha:=Alpha-(255-eColor.alpha); //<- added
    ec.alpha := Alpha shl 8+Alpha;
    result := GammaCompression(ec);
everything is ok with alpha from 230 - 255, with more transparency I see a little mess on the corners.

I attached sample test project. @circular can you look at this ?
Title: Re: BGRABitmap tutorial
Post by: circular on June 23, 2011, 05:47:15 pm
Ok. I've added a similar line.
Title: Re: BGRABitmap tutorial
Post by: tomek on June 24, 2011, 11:15:50 am
Great, everything works fine :)
Title: Re: BGRABitmap tutorial
Post by: circular on June 24, 2011, 11:56:06 am
I've added TBGRAScene3D object which makes it easier to draw 3D shapes. There is no online tutorial for now, but you can find examples in testbgrafunc folder. Last version of BGRABitmap is available as a zip file here :
https://sourceforge.net/projects/lazpaint/files/src/

Here is an example to create a 3D cube :
Code: [Select]
unit ucube3d;

{$mode objfpc}

interface

uses
  Classes, SysUtils, BGRAScene3D, BGRABitmapTypes;

type

  { TCubeScene3D }

  TCubeScene3D = class(TBGRAScene3D)
    cube: IBGRAObject3D;
    constructor Create;
    procedure SetCubeTexture(ATexture: TBGRACustomBitmap);
    procedure SetCubeTexture(ATexture: IBGRAScanner; tx,ty: single);
  end;

implementation

{ TCubeScene3D }

constructor TCubeScene3D.Create;
var v: arrayOfIBGRAVertex3D;
begin
  inherited Create;

  cube := CreateObject;
  v := cube.Vertices.Add([-1,-1,-1, 1,-1,-1, 1,1,-1, -1,1,-1,
                          -1,-1,+1, 1,-1,+1, 1,1,+1, -1,1,+1]);

  cube.AddFace([v[0],v[1],v[2],v[3]],BGRA(255,0,0));
  cube.AddFace([v[4],v[5],v[1],v[0]],BGRA(128,160,255));
  cube.AddFace([v[7],v[6],v[5],v[4]],BGRA(96,224,0));
  cube.AddFace([v[3],v[2],v[6],v[7]],BGRA(192,0,255));
  cube.AddFace([v[1],v[5],v[6],v[2]],BGRA(255,192,0));
  cube.AddFace([v[4],v[0],v[3],v[7]],BGRAWhite);

  cube.Vertices.Scale(20);

  AmbiantLight := 0.25;
  AddLight(Point3D(1,1,1),1.25);
end;

procedure TCubeScene3D.SetCubeTexture(ATexture: TBGRACustomBitmap);
begin
  SetCubeTexture(ATexture,ATexture.Width-1,ATexture.Height-1);
end;

procedure TCubeScene3D.SetCubeTexture(ATexture: IBGRAScanner; tx, ty: single);
var
  i: Integer;
begin
  for i := 0 to cube.FaceCount-1 do
  with cube.Face[i] do
  begin
    Texture := ATexture;
    TexCoord[0] := PointF(0,0);
    TexCoord[1] := PointF(tx,0);
    TexCoord[2] := PointF(tx,ty);
    TexCoord[3] := PointF(0,ty);
  end;
end;

end.
Title: Re: BGRABitmap tutorial
Post by: circular on June 25, 2011, 04:10:01 pm
Added Phong shading to 3D rendering.

https://sourceforge.net/projects/lazpaint/files/src/

Here is a screenshot :
Title: Re: BGRABitmap tutorial
Post by: martinrame on June 26, 2011, 08:37:24 pm
Hi Circular, I would like to know how can I set the stroke color in Canvas2D.

If I do this:

Code: [Select]
  Abmp.Canvas2D.strokeStyle(clGreen);
  Abmp.Canvas2D.LineTo(....)
  Abmp.Canvas2D.stroke;   

  Abmp.Canvas2D.strokeStyle(clRed);
  Abmp.Canvas2D.LineTo(....)
  Abmp.Canvas2D.stroke;   

Everything is drawn in clRed, instead of the first line in Green and second in Red.
Title: Re: BGRABitmap tutorial
Post by: circular on June 26, 2011, 09:54:02 pm
You need to call beginPath before you add points. If you don't, the last points are still in the path and are redrawn. So your code should be something like :
Quote
  Abmp.Canvas2D.strokeStyle(clGreen);
  Abmp.Canvas2D.beginPath;
  Abmp.Canvas2D.moveTo(...);
  Abmp.Canvas2D.lineTo(....)
  Abmp.Canvas2D.stroke;   

  Abmp.Canvas2D.strokeStyle(clRed);
  Abmp.Canvas2D.beginPath;
  Abmp.Canvas2D.moveTo(...);
  Abmp.Canvas2D.lineTo(....)
  Abmp.Canvas2D.stroke;   
Title: Re: BGRABitmap tutorial
Post by: circular on July 02, 2011, 12:55:59 pm
Hello people. 3D lighting works well now (version 4.5). I will do some tutorial soon.
Title: Re: BGRABitmap tutorial
Post by: lainz on July 02, 2011, 03:18:11 pm
Nice! I'm waiting to do some 3d with code.
Title: Re: BGRABitmap tutorial
Post by: circular on July 02, 2011, 10:36:11 pm
The wiki is not working, so I did an application with simple examples with comments. It's on subversion. I've fixed some things in BGRABitmap too.

There is also a zip available on source forge (version 4.6).
http://sourceforge.net/projects/lazpaint/files/src/
Title: Re: BGRABitmap tutorial
Post by: lainz on July 03, 2011, 01:45:36 am
The wiki is not working, so I did an application with simple examples with comments. It's on subversion. I've fixed some things in BGRABitmap too.

There is also a zip available on source forge (version 4.6).
http://sourceforge.net/projects/lazpaint/files/src/

Is possible to create a wiki in sourceforge?
Title: Re: BGRABitmap tutorial
Post by: circular on July 03, 2011, 10:57:16 am
I suppose it is possible, because it is possible to create any web site with it. But I guess there is no embedded wiki.
Title: Re: BGRABitmap tutorial
Post by: circular on July 06, 2011, 06:53:39 pm
Ok, here are the first 3D tutorials :
http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_15
Title: Re: BGRABitmap tutorial
Post by: tomek on July 07, 2011, 10:31:51 am
I found that Phong (BGRAGradients) can draw Cone but only "top view".
Is there function which draw front view of cone ? I want to draw something like that http://infocenter.sybase.com/help/topic/com.sybase.infocenter.dc01261.1200/doc/html/kwi1243870832587.html (http://infocenter.sybase.com/help/topic/com.sybase.infocenter.dc01261.1200/doc/html/kwi1243870832587.html)
Title: Re: BGRABitmap tutorial
Post by: circular on July 07, 2011, 05:08:53 pm
It's not possible with 2D phong, you need 3D rendering to do that. I'm developping TBGRAScene3D for this. You can already do something like that with it by specifying a polyhedron that approximates a cone.
Title: Re: BGRABitmap tutorial
Post by: lainz on July 12, 2011, 04:04:08 am
The new TBGRATextEffect is really cool!

The quality of the outline effect its really nice.
Title: Re: BGRABitmap tutorial
Post by: circular on July 13, 2011, 09:46:47 am
It's just what we already talked about.  8-)
Title: Re: BGRABitmap tutorial
Post by: Fred vS on July 13, 2011, 12:33:31 pm
Sorry to disturb you one more time but...still no plan for a alpha-blended panel component ?
Thanks
Title: Re: BGRABitmap tutorial
Post by: lainz on July 13, 2011, 03:58:27 pm
Sorry to disturb you one more time but...still no plan for a alpha-blended panel component ?
Thanks

The problem is TControls that doesn't support alpha.

Really support alpha but in a non crossplatform way (from what I understand).
Title: Re: BGRABitmap tutorial
Post by: Fred vS on July 13, 2011, 04:12:49 pm
Quote
The problem is TControls that doesn't support alpha.

 :'(
Title: Re: BGRABitmap tutorial
Post by: lainz on July 13, 2011, 04:25:15 pm
I think we can do something if we use include files.

Something like:

{$IFDEF WINDOWS}
bgracontrolwin.inc

Code: [Select]
TBGRAControl=(TControl)
Using the trick for Adding alpha support in Windows TControl and the other OS's has alpha support by default.

{ELSE}

bgracontrol.inc

Code: [Select]
TBGRAControl=(TControl)
// Default TControl

{$ENDIF}
Title: Re: BGRABitmap tutorial
Post by: circular on July 13, 2011, 07:27:22 pm
Sorry to disturb you one more time but...still no plan for a alpha-blended panel component ?
Thanks
What do you want to do ? Maybe it's possible without it.
Title: Re: BGRABitmap tutorial
Post by: lainz on July 13, 2011, 09:19:06 pm
not read minds =D

but I would use it to add in bgrabutton and make a kind of menu. show or hide the panel would be easier to hide and show all the buttons one by one.
Title: Re: BGRABitmap tutorial
Post by: Fred vS on July 13, 2011, 09:58:37 pm
@ Mr Circular :

Here a topic (with no answer) about that famous alpha-blended-shaped panels :

http://www.lazarus.freepascal.org/index.php/topic,12784.msg66166.html#msg66166 (http://www.lazarus.freepascal.org/index.php/topic,12784.msg66166.html#msg66166)

a other :

http://www.lazarus.freepascal.org/index.php/topic,12037.msg66527.html#msg66527 (http://www.lazarus.freepascal.org/index.php/topic,12037.msg66527.html#msg66527)

Thanks
Title: Re: BGRABitmap tutorial
Post by: circular on July 13, 2011, 11:10:56 pm
@Fred vS: that's not my question. I invited you to tell me precisely what you want to do, in which context, to see if there is another way.
Title: Re: BGRABitmap tutorial
Post by: Fred vS on July 13, 2011, 11:45:59 pm
Hello Mr Circular.

First i want a shaped panel, like showed in the topic of shaped panel to create a custom hint, with alphablended properties.

Also i develop a DJ program (miXimum) and i want to use that alphablended panel for the waves-forms, easier to synchronize two songs.

Also it could be a great effect if the players (panels) could appear and disappear after mixing (with alphablend effect)..
Title: Re: BGRABitmap tutorial
Post by: Fred vS on July 14, 2011, 12:12:20 am
Is TBGRA available for OS X too ?
I do not have find the download-file in source-forge (only Win and Linux)  %)
Title: Re: BGRABitmap tutorial
Post by: lainz on July 14, 2011, 12:48:28 am
Is TBGRA available for OS X too ?
I do not have find the download-file in source-forge (only Win and Linux)  %)

Download file? The file is for LazPaint. The source is cross platform.

https://sourceforge.net/projects/lazpaint/files/src/
Title: Re: BGRABitmap tutorial
Post by: Fred vS on July 14, 2011, 12:58:22 am
@ Lainz

Ok, perfect, i gonna use it.
Title: Re: BGRABitmap tutorial
Post by: circular on July 14, 2011, 09:37:29 am
Hello Mr Circular.

First i want a shaped panel, like showed in the topic of shaped panel to create a custom hint, with alphablended properties.

Also i develop a DJ program (miXimum) and i want to use that alphablended panel for the waves-forms, easier to synchronize two songs.

Also it could be a great effect if the players (panels) could appear and disappear after mixing (with alphablend effect)..
Ok well, it would be possible to create a transparent virtual screen, but without components in it. That means that you would have to program interactions with the elements inside the panel yourself by handling the mouse events for the whole panel. In other words, you can do what you want if you don't put components into it, and if the program draws and handles the components by itself.

If this is ok, you just need that transparent virtual screen component.
Title: Re: BGRABitmap tutorial
Post by: CaptBill on July 14, 2011, 09:56:04 am
Hello Mr Circular.

First i want a shaped panel, like showed in the topic of shaped panel to create a custom hint, with alphablended properties.

Also i develop a DJ program (miXimum) and i want to use that alphablended panel for the waves-forms, easier to synchronize two songs.

Also it could be a great effect if the players (panels) could appear and disappear after mixing (with alphablend effect)..
Ok well, it would be possible to create a transparent virtual screen, but without components in it. That means that you would have to program interactions with the elements inside the panel yourself by handling the mouse events for the whole panel. In other words, you can do what you want if you don't put components into it, and if the program draws and handles the components by itself.

If this is ok, you just need that transparent virtual screen component.

This could be really nice for doing ownerdraw components for ultimate control of the painting of the interface.

Imagine a custom built interface and even your components are drawn by BGRAbitmap, plus transparency.
Title: Re: BGRABitmap tutorial
Post by: martinrame on July 17, 2011, 05:42:00 pm
Hi Circular, I have two questions about Canvas2D.

1) How can I clear the canvas?. There's no myCanvas2".clear method.
2) How can I create a shadow to an element in Canvas2D. Could you add a shadow to this example:

Code: [Select]
Fbmp.Canvas2D.strokeStyle(clRed);
Fbmp.Canvas2D.beginPath;
Fbmp.Canvas2D.moveTo(10,10);
Fbmp.Canvas2D.lineTo(200,200);
Fbmp.Canvas2D.stroke;

Fbmp is a TBGRABitmap that draws over a TPaintBox containing an image that acts as background for my vectors drawn with Canvas2D.

Thanks in advance,
Martin.
Title: Re: BGRABitmap tutorial
Post by: circular on July 18, 2011, 01:00:10 am
1) To clear the canvas, there is a clearRect method and clearPath method. You can also use surface property to get access to standard function like Fill which is faster. In your example, you can just write
Code: [Select]
Fbmp.Fill(someColor);
2) To create a shadow you must specify the offset, the color and the blur radius of the shadow :
Code: [Select]
Fbmp.Canvas2D.shadowColor(clBlack);
Fbmp.Canvas2D.shadowOffset := PointF(5,5);
Fbmp.Canvas2D.shadowBlur := 3;

The shadow is drawn along with stroke and fill methods.
Title: Re: BGRABitmap tutorial
Post by: Fred vS on July 18, 2011, 01:10:30 am
@ CaptBill

Quote
Imagine a custom built interface and even your components are drawn by BGRAbitmap, plus transparency.

Yep, for example a BGRAStringgrid with alphablend so, with a timer, you could fade it in and out, whouaw  ;)
Title: Re: BGRABitmap tutorial
Post by: lainz on July 22, 2011, 06:29:45 pm
@circular

Is possible to implement in the Object Inspector:

Color : TBGRAPíxel
Bitmap : TBGRABitmap

?
Title: Re: BGRABitmap tutorial
Post by: circular on July 22, 2011, 10:27:12 pm
I have no idea.
Title: Re: BGRABitmap tutorial
Post by: lainz on July 25, 2011, 05:06:32 pm
I have no idea.

I think is a form with code. With my little experience could not do this =)

Yo've seen spktoolbar? It has an editor in the folder "designtime".

https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/components/spktoolbar

Also jedi code format (jcf in the lazarus component folder) is integrated in the IDE.
Title: Re: BGRABitmap tutorial
Post by: circular on July 26, 2011, 08:52:29 pm
Here is version 4.7 with :
- BGRATextFX
- dmXor : xor drawing mode

http://sourceforge.net/projects/lazpaint/files/src/
Title: Re: BGRABitmap tutorial
Post by: circular on July 26, 2011, 08:55:48 pm
I think is a form with code. With my little experience could not do this =)

Yo've seen spktoolbar? It has an editor in the folder "designtime".

https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/components/spktoolbar

Also jedi code format (jcf in the lazarus component folder) is integrated in the IDE.
Apparently, they register the form with RegisterPropertyEditor.
Title: Re: BGRABitmap tutorial
Post by: lainz on July 26, 2011, 10:04:35 pm
I think is a form with code. With my little experience could not do this =)

Yo've seen spktoolbar? It has an editor in the folder "designtime".

https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/components/spktoolbar

Also jedi code format (jcf in the lazarus component folder) is integrated in the IDE.
Apparently, they register the form with RegisterPropertyEditor.

Take a look at this:

~laz\ideintf\
graphpropedits.pas
graphicpropedit.pas
graphicpropedit.lfm

{ TGraphicPropertyEditor
  The default property editor for all TGraphic's and sub types (e.g. TBitmap,
  TPixmap, TIcon, etc.). }

{ TPicturePropertyEditor
  The default property editor for TPicture}

{ TColorPropertyEditor
  PropertyEditor editor for the TColor type. Displays the color as a clXXX value
  if one exists, otherwise displays the value as hex.  Also allows the
  clXXX value to be picked from a list. }
Title: Re: BGRABitmap tutorial
Post by: joseywales72 on July 27, 2011, 03:46:52 pm
Hi,
First of all, thank you very much Circular. Your library is pure gold.

I've a problem though, but I'm sure it is because of my stupidity. Anyway here it is.
I'm trying to blend two images from top to bottom. But to no use.. Here is the code.

Code: [Select]
resim1 := TBGRABitmap.Create(resim1dosya);  // A jpeg file
onizleme := resim1.Resample(512,384) as TBGRABitmap;   // image resized to 512x384
maske:=TBGRABitmap.Create(512,384); // a 512x384 mask image
maske.GradientFill(0,0,maske.Width,maske.Height,BGRA(255,255,255),BGRA(0,0,0),gtLinear,PointF(0,0),PointF(0,maske.Height),dmSet); // A white to black gradient for mask
onizleme.ApplyMask(maske); //Mask is applied
sonresim:=TBGRABitmap.Create(512,384); //Final image
sonresim.PutImage(0,0,onizleme,dmDrawWithTransparency); // Final image is rendered
sonresim.Draw(Panel1.Canvas,0,0,True); // and drawn to canvas..
onizleme.Free; 
resim1.Free;
maske.free;
sonresim.Free;   // all resources are freed..           

Problem is, I was hoping for a gradual vertical transparency in the final image, but the image is like there is no mask applied. Clearly I'm doing something wrong, but what?

I'd appreciate any help.
Thank you.
PS. Sorry for probable mistakes, I'm not a native speaker.
Anil
Title: Re: BGRABitmap tutorial
Post by: lainz on July 27, 2011, 08:36:57 pm
Don't use TPanel, use TBGRAVirtualScreen instead (is available in BGRAControls package).

This code works:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.BGRAVirtualScreen1Redraw(Sender: TObject; Bitmap: TBGRABitmap);
  2. var
  3.   image, mask: TBGRABitmap;
  4. begin
  5.   { Background Image }
  6.   image := TBGRABitmap.Create('C:\image1.jpg');
  7.   BGRAReplace(image, image.Resample(512, 384));
  8.   Bitmap.PutImage(0, 0, image, dmSet);
  9.   image.Free;
  10.  
  11.   { Masked Image }
  12.   image := TBGRABitmap.Create('C:\image2.jpg');
  13.   BGRAReplace(image, image.Resample(512, 384));
  14.  
  15.   mask := TBGRABitmap.Create(image.Width, image.Height);
  16.   mask.GradientFill(0, 0, image.Width, image.Height, BGRAWhite, BGRABlack,
  17.     gtLinear, PointF(0, 0), PointF(0, image.Height), dmSet, True, False);
  18.  
  19.   image.ApplyMask(mask);
  20.   mask.Free;
  21.  
  22.   Bitmap.PutImage(0, 0, image, dmDrawWithTransparency);
  23.   image.Free;
  24. end;
Title: Re: BGRABitmap tutorial
Post by: circular on July 28, 2011, 03:19:19 pm
@joseywales72:

The last parameter of Draw is a boolean that specifies if the image is opaque. You must put "False" to have a transparent rendering.

Your code then works on Windows, but will not render correctly on Mac OS, since it is not drawn inside an OnPaint event. As lainz said, you should use a paintable control, for example TBGRAVirtualScreen (there are bevel options so you can have something like a panel).

Another remark, when you apply the mask, the image becomes transparent, and you can draw it directly. You don't need to use another image (sonresim).

@lainz:

You're code is perfect.
Title: Re: BGRABitmap tutorial
Post by: joseywales72 on July 30, 2011, 11:01:17 am
Thank you circular and lainz, both for the answers and the brilliant libraries...
I just upgraded to 4.7 from 4.6.1 and I'm going to try. I forgot my code at work but I'll try to access it remotely.
Anil
Title: Re: BGRABitmap tutorial
Post by: Dibo on July 31, 2011, 02:56:25 pm
I am looking for easy way to color words. For example:

This is some long text with colored words and word break

Words will be have very simple tags. Anyone know how to do that? Maybe BGRABitmap have some interesting methods? My only idea is to draw text char by char with own word break algorithm.
Title: Re: BGRABitmap tutorial
Post by: circular on July 31, 2011, 07:34:52 pm
@dibo: you can do that with TBGRATextEffect class.

To do this, call DrawMulticolored and as color array use :
[black *6, blue*4, black*4, red*4 etc.]

Note : this works only if letters are clearly separated. If two letters share the same column of pixels, they are considered to be one block.

Otherwise, you need to split the text into parts of the same color. It's faster to draw a word with one color than to draw each letter separately.
Title: Re: BGRABitmap tutorial
Post by: Dibo on July 31, 2011, 08:16:51 pm
Thanks for tip. I will try this solution
Title: Re: BGRABitmap tutorial
Post by: martinrame on August 08, 2011, 04:58:54 pm
Hi circular, I'm looking for a way to adjust brightness and contrast of an RGB image. Does TBGRABitmap have such method?.
Title: Re: BGRABitmap tutorial
Post by: circular on August 09, 2011, 01:59:55 pm
You can use FilterNormalize(False) to use full intensity range, but it may not be what you want to do. Otherwise you can use GetIntensity/SetIntensity and GetLightness/SetLightness for each pixel. See for example ucolorintensity.pas of LazPaint in the ApplyIntensity procedure.
Title: Re: BGRABitmap tutorial
Post by: martinrame on August 09, 2011, 03:12:45 pm
Thanks, it was not exactly what I was looking for, but I has helped a lot. I used the SetIntensity method from Lazpaint.
Title: Re: BGRABitmap tutorial
Post by: martinrame on September 24, 2011, 11:45:43 am
I created an application that basically show a big image at background and several vectors (with canvas2d) over it. The user can drag or modify those vectors.

To draw, each vector draws on its own TBrabitmap then call its method Draw to copy to Paintbox canvas, on OnPaint event.

The problem is that as much vectors I add, the drawing becomes more and more slow.

Every time I call Invalidate on the PaintBox, it does a canvas.clear, then re-draws everything. Is there a way to only update the changed regions?

How do you recommend to approach this problem?.
Title: Re: BGRABitmap tutorial
Post by: circular on September 24, 2011, 08:56:39 pm
You should merge the drawing in a virtual screen, for example using TBGRAVirtualScreen, instead of drawing many BGRABitmap directly on the screen. The less direct drawing you have, the faster it is. Thus, if you store the result of each vector in a TBGRABitmap, then when you change one of them, you only have to rebuild the bitmap attached to it, and then merge everything in a virtual screen.

You may also consider not using temporary bitmaps and drawing directly with canvas2D on the TBGRAVirtualScreen.
Title: Re: BGRABitmap tutorial
Post by: martinrame on September 26, 2011, 01:24:17 am
Thanks circular. As far as I understand, and trying to avoid TBGRAVirtualScreen, I can use many TBGRABitmaps for the vectors, then just before drawing, I can copy all of them to a bmp.Canvas called, say "plainCanvas", then in the onPaint event of the PaintBox, I should copy that  "plainCanvas" to the Paintbox.Canvas.

Here's a simple program to show the concept:

Code: [Select]
procedure TForm1.FormCreate(Sender: TObject);
begin
  FBmp1 := TBGRABitmap.Create(400, 400); // FBmp1 is the "plainCanvas"
  FVect1 := TBGRABitmap.Create(400, 400);
  FVect2 := TBGRABitmap.Create(400, 400);

  // draw temp vect1
  FVect1.Canvas2D.lineWidth:= 2;
  FVect1.Canvas2D.strokeStyle(clGreen);
  FVect1.Canvas2D.fillStyle(clYellow);
  FVect1.Canvas2D.beginPath;
  FVect1.Canvas2D.strokeRect(20,20, 200,20);
  FVect1.Canvas2D.fillRect(21,21, 198,18);
  FVect1.Canvas2D.stroke;

  // draw temp vect2
  FVect2.Canvas2D.lineWidth:= 2;
  FVect2.Canvas2D.strokeStyle(clRed);
  FVect2.Canvas2D.beginPath;
  FVect2.Canvas2D.strokeRect(40,10, 100,100);
  FVect2.Canvas2D.stroke;
end;

procedure TForm1.CopyVectorsToBitmap;
var
  lRect: TRect;
begin
  lRect := FVect1.ClipRect;
  FBmp1.Canvas.CopyRect( lRect, FVect1.Canvas, lRect );
  FBmp1.Canvas.CopyRect( lRect, FVect2.Canvas, lRect );
  Invalidate;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  // copy "plainCanvas" to screen or PaintBox, or whatever
  FBmp1.Draw(Self.Canvas,0, 0, False);
end;

Does it only draws to screen in FormPaint? or every time I call Canvas.CopyRect there's screen intervention?.

BTW, the only method to copy a TBgraBitmap to another is using canvas.copyrect?.
Title: Re: BGRABitmap tutorial
Post by: martinrame on September 26, 2011, 04:38:38 pm
Quick question. How can I clear a BGRABitmap?.

Apparently the method Canvas.Clear does not clear the image.

What i'm doing is freeing the bgrabitmap and re-creating it every time I have to redraw some vectors over it. But I thinks this is too overwhelming.
Title: Re: BGRABitmap tutorial
Post by: circular on September 26, 2011, 07:04:45 pm
@martinrame:

You should not use Canvas property of BGRABitmap unless you have no choice, because it is slower. Instead, to copy bitmaps, use PutImage.

To clear a bitmap, call Fill or FillTransparent.
Title: Re: BGRABitmap tutorial
Post by: martinrame on September 26, 2011, 08:08:35 pm
Thanks circular. Using FillTransparent and PutImage did the job.

Quote
You should not use Canvas property of BGRABitmap unless you have no choice, because it is slower.

Now everything runs much faster. I only have one BgraBitmap.Draw(PaintBox.Canvas....), if I replace my paintbox with a TBGRAVirtualScreen, do you think the drawing speed will improve even more?.
Title: Re: BGRABitmap tutorial
Post by: circular on September 26, 2011, 10:35:32 pm
No, it will be the same speed. But it avoids flickering too. Anyway you can do this by yourself by redefining the erase background event :
Code: [Select]
procedure WMEraseBkgnd(var Message: TLMEraseBkgnd); message LM_ERASEBKGND;

...

procedure TForm1.WMEraseBkgnd(var Message: TLMEraseBkgnd);
begin
  //do nothing
end;
Title: Re: BGRABitmap tutorial
Post by: martinrame on September 27, 2011, 08:35:00 pm
Hi, I'm using Canvas2D and can't find how to draw dotted or dashed lines.

If it's not possible, is there a way to draw antialiased dotted and/or dashed lines in BGRABitmap?.

Thanks in advance.

SOLVED!!!

To draw dashes use myBitmap.Canvas2d.lineStyle[5,2] (5 pixels and 2pixel space).
To draw dots use myBitmap.Canvas2d.lineStyle[1,2] (1 pixel, 2 spaces).
Title: Re: BGRABitmap tutorial
Post by: circular on September 27, 2011, 09:18:47 pm
That's right.
Title: Re: BGRABitmap tutorial
Post by: martinrame on October 12, 2011, 09:53:30 pm
How can I print a TBgraBitmap to a printer.

I tried this, but it prints an empty page:

Code: [Select]
with Printer do
try
  BeginDoc;
  Printer.Canvas.CopyRect(
    Rect(0, 0, Printer.PageWidth, Printer.PageHeight),
    FBmp.Canvas,
    Rect(0, 0, FBmp.Width, FBmp.Height)
  );
finally
  EndDoc
end;

FBmp is my TBGRABitmap.
Title: Re: BGRABitmap tutorial
Post by: martinrame on October 12, 2011, 10:22:25 pm
Well, this did the trick...but it's slow:

Quote
with Printer do
try
  BeginDoc;
  Canvas.Draw(0, 0, FBmp.Bitmap);
finally
  EndDoc;
end;

Please, let me know if you know a faster way to copy TBGRABitmap to TPrinter.Canvas.
Title: Re: BGRABitmap tutorial
Post by: lainz on October 13, 2011, 12:18:21 am
I don't know if it is faster or if it works but try:

Code: [Select]
FBmp.Bitmap.Canvas instead
Code: [Select]
FBmp.Canvas
Title: Re: BGRABitmap tutorial
Post by: circular on October 13, 2011, 12:47:00 pm
What about :
Code: [Select]
with Printer do
try
  BeginDoc;
  FBmp.Draw(Canvas,0,0);
finally
  EndDoc;
end;
Title: Re: BGRABitmap tutorial
Post by: martinrame on October 20, 2011, 08:21:10 pm
Circular, I've uploaded a showcase of a Dicom Viewer i've written using BGRABitmap.

Please, take a look:

http://www.youtube.com/watch?v=hc1RT-s-dw0 (http://www.youtube.com/watch?v=hc1RT-s-dw0)

Thank you for this wonderful library.

Leonardo M. Ramé
http://leonardorame.blogspot.com (http://leonardorame.blogspot.com)
Title: Re: BGRABitmap tutorial
Post by: circular on October 20, 2011, 09:15:49 pm
Wow this is really a cool program !  :)

I'm proud to have participated to it.  8)
Title: Re: BGRABitmap tutorial
Post by: fabienwang on October 22, 2011, 02:52:28 pm
Circular, I've uploaded a showcase of a Dicom Viewer i've written using BGRABitmap.

Please, take a look:

http://www.youtube.com/watch?v=hc1RT-s-dw0 (http://www.youtube.com/watch?v=hc1RT-s-dw0)

Thank you for this wonderful library.

Leonardo M. Ramé
http://leonardorame.blogspot.com (http://leonardorame.blogspot.com)

Amazing soft :)
Title: Re: BGRABitmap tutorial
Post by: mica on October 22, 2011, 04:20:51 pm
Wow.
This Viewer is really great software.
Title: Re: BGRABitmap tutorial
Post by: circular on October 24, 2011, 11:01:43 pm
Here is a new version of BGRABitmap (5.0) with :
- simple stretch smaller optimization
- more phong shapes
- text phong shading (using TBGRATextEffect.DrawShaded with TPhongShading)

http://sourceforge.net/projects/lazpaint/files/src/
Title: Re: BGRABitmap tutorial
Post by: circular on October 26, 2011, 02:45:01 am
Just added new features on subversion :

FontFullHeight : always the real font height in pixels
FillClearTypeMask : used by clear type fonts, but if you want you can draw any shape with cleartype
FontQuality : to specify if the font rendering is system, fine antialiased or cleartype
FillMask : fill with a color or a texture a part of the bitmap using a mask, thus you can avoid to do ApplyMask+PutImage.
Title: Re: BGRABitmap tutorial
Post by: gyts on October 30, 2011, 11:14:58 am
How to do 1 without doing 2?
Title: Re: BGRABitmap tutorial
Post by: circular on October 30, 2011, 11:44:58 am
Please explain what you mean.
Title: Re: BGRABitmap tutorial
Post by: gyts on October 30, 2011, 12:08:20 pm
I need to move blue line everywhere but it should stay under yellow without repainting those lines as shown in 2 picture
Title: Re: BGRABitmap tutorial
Post by: martinrame on October 30, 2011, 02:33:29 pm
@gyts, I think you need to clean the bgrabitmap before redrawing.

One strategy I use for this is doing all the drawings on a TPaintBox, by overriding its onPaint event.

Here's more or less how the onPaint event should look:

Code: [Select]
procedure TForm1.PaintBox1OnPaint(Sender: TObject);
var
  lBMP: TBGRABitmap;

begin
  lBMP := TBGRABitmap.Create(100, 100);
  try
   (* start drawing stuff *)
    lBmp.Canvas.Line ...
   (* End drawing stuff *)
   lBmp.Draw(PaintBox1.Canvas, 0, 0);
  finally
    lBmp.Free;
  end;
end;

So, every time you need to re-draw your vectors, for example after a keypress event, you call "Paintbox1.invalidate" and the image is redrawn.
Title: Re: BGRABitmap tutorial
Post by: circular on October 30, 2011, 03:52:11 pm
@gyts:
you can also use bitmap.Fill(BGRAWhite) to clear it before you draw it again.
Title: Re: BGRABitmap tutorial
Post by: circular on October 31, 2011, 05:03:35 pm
Here is a new version of BGRABitmap (5.1) with:
- font pixel metric : you can get the position of font lines (baseline, top of caps...) with FontPixelMetric property
- big font optimization : big font are faster
- improved readability : for small and medium fonts, it's easier to read, like system rendering

http://sourceforge.net/projects/lazpaint/files/src/
Title: Re: BGRABitmap tutorial
Post by: Shebuka on November 02, 2011, 05:31:21 pm
I need to move blue line everywhere but it should stay under yellow without repainting those lines as shown in 2 picture
First paint all blue lines, then paint all yellow lines? i think you can't do this without repainting.
Title: Re: BGRABitmap tutorial
Post by: circular on November 06, 2011, 01:20:38 pm
Here is a new version (5.2) with :
- system ClearType to render text like with clearType effect exactly like system do (see screenshot below)
- vertical align improvement for small fonts

http://sourceforge.net/projects/lazpaint/files/src/
Title: Re: BGRABitmap tutorial
Post by: lainz on November 06, 2011, 04:08:07 pm
Fine ClearType IS the font. The best quality never seen.
Title: Re: BGRABitmap tutorial
Post by: circular on November 06, 2011, 05:24:23 pm
In this case, yes, because the font has an orientation. On Windows, at least, standard oriented text rendering is ugly. When there is no special orientation, system ClearType is ok :
Title: Re: BGRABitmap tutorial
Post by: lainz on November 19, 2011, 02:37:07 pm
There is a function to get text width and height when the 'caption' has several lines?

When I want to draw using TextRect with WordBreak.
Title: Re: BGRABitmap tutorial
Post by: circular on November 19, 2011, 03:07:04 pm
No.
Title: Re: BGRABitmap tutorial
Post by: lainz on November 19, 2011, 05:35:48 pm
Mm ok.

I'm trying to understand the customlabel.inc that has working AutoSize and WordWrap to use that code with bgra fonts.
Title: Re: BGRABitmap tutorial
Post by: circular on November 19, 2011, 07:42:16 pm
Good idea.
Title: Re: BGRABitmap tutorial
Post by: circular on November 27, 2011, 05:07:44 pm
Here is a new version (5.3) of BGRABitmap with layer support (in BGRALayers) :

http://sourceforge.net/projects/lazpaint/files/src/

How to use :
Code: [Select]
  layers := TBGRALayeredBitmap.Create(640,480);
  layers.AddLayer(someBmp,128);
  layers.AddLayerFromFile('filename1');
  layers.LayerOpacity[layers.AddLayerFromFile('filename1')] := 128;
  ...
  layers.Draw(bmp,0,0);
  ...
  layers.free;
Title: Re: BGRABitmap tutorial
Post by: circular on November 28, 2011, 01:16:30 am
New version (5.4) :
- blend op string conversion
- layer offset, layer bitmap access
- owned layer, optimization and bug fix

Here is a screenshot :
Title: Re: BGRABitmap tutorial
Post by: lainz on December 11, 2011, 01:38:10 am
I've added 'Animation' in TBGRAImageButton, basically it call Invalidate every 20 ms.

To create a 'fade' effect I do PutImage in this way:

Code: [Select]
     
..
bsHot: begin
        FBGRA.PutImage(0, 0, FBGRAUp, dmDrawWithTransparency);
        FBGRA.PutImage(0, 0, FBGRAHot, dmDrawWithTransparency, FTimerStep);
      end;   
..
 

This works fine in squared buttons, but with the image of the 'bigeyes' ( http://wiki.lazarus.freepascal.org/Image:samplebgraimagebuttonalpha.png ) I get an error External: SIGFPE in the line 3379 of bgradefaultbitmap

To reproduce this check the latest git sources of BGRAControls and mouse over the top right image button (the bigeyes one).

I'm doing something wrong?
Title: Re: BGRABitmap tutorial
Post by: circular on December 11, 2011, 11:19:51 am
I think it's a problem of compilation. Just remove old binaries and it should work. But looking at the code, I realized there was a little error un BGRABitmap, and that you code could be improved.

I propose you to replace TCustomBGRAImageButton.UpdateBmp code by this :

Code: [Select]
procedure CustomReplace(var Destination: TBGRACustomBitmap; Temp: TObject);
begin
  Destination.Free;
  Destination := Temp as TBGRACustomBitmap;
end;

var
  TBmp: TBGRABitmap;
begin
  if csLoading in ComponentState then
    exit;

  if (Bitmap = nil) or (Bitmap.Width < 1) and (Bitmap.Height < 1) then
    exit;

  FBmpHeight := Bitmap.Height div 4;

  FBGRA.SetSize(Width, Height);

  TBmp := TBGRABitmap.Create(FBmp);

  //get pointer bitmaps
  FreeAndNil(FBGRAUp);
  FBGRAUp := TBmp.GetPtrBitmap(0,FBmpHeight);
  FBGRAUp.ResampleFilter:= rfBestQuality;
  FreeAndNil(FBGRAHot);
  FBGRAHot := TBmp.GetPtrBitmap(FBmpHeight,FBmpHeight*2);
  FBGRAHot.ResampleFilter:= rfBestQuality;
  FreeAndNil(FBGRADown);
  FBGRADown := TBmp.GetPtrBitmap(FBmpHeight*2,FBmpHeight*3);
  FBGRADown.ResampleFilter:= rfBestQuality;
  FreeAndNil(FBGRADisabled);
  FBGRADisabled := TBmp.GetPtrBitmap(FBmpHeight*3,FBmpHeight*4);
  FBGRADisabled.ResampleFilter:= rfBestQuality;

  if BitmapOptions.Enable then
  begin
    CustomReplace(FBGRAUp,CustomResizeBitmap(FBGRAUp,BitmapOptions.BorderWidth,BitmapOptions.BorderHeight,Width,Height,BitmapOptions.DrawMode,BitmapOptions.ResampleMode,BitmapOptions.ResampleFilter));
    CustomReplace(FBGRADown,CustomResizeBitmap(FBGRADown,BitmapOptions.BorderWidth,BitmapOptions.BorderHeight,Width,Height,BitmapOptions.DrawMode,BitmapOptions.ResampleMode,BitmapOptions.ResampleFilter));
    CustomReplace(FBGRAHot,CustomResizeBitmap(FBGRAHot,BitmapOptions.BorderWidth,BitmapOptions.BorderHeight,Width,Height,BitmapOptions.DrawMode,BitmapOptions.ResampleMode,BitmapOptions.ResampleFilter));
    CustomReplace(FBGRADisabled,CustomResizeBitmap(FBGRADisabled,BitmapOptions.BorderWidth,BitmapOptions.BorderHeight,Width,Height,BitmapOptions.DrawMode,BitmapOptions.ResampleMode,BitmapOptions.ResampleFilter));
  end
  else
  begin //needed even if same size in order to make a real copy
    CustomReplace(FBGRAUp, FBGRAUp.Resample(Width, Height));
    CustomReplace(FBGRADown, FBGRADown.Resample(Width, Height));
    CustomReplace(FBGRAHot, FBGRAHot.Resample(Width, Height));
    CustomReplace(FBGRADisabled, FBGRADisabled.Resample(Width, Height));
  end;

  TBmp.Free;

  InvalidatePreferredSize;
  AdjustSize;

  if Sender is TBitmap then
    Invalidate;

  {$IFDEF DEBUG}
  Inc(FUpdateCount);
  {$ENDIF}
end;         

And to use this code in the constructor :
Code: [Select]
  FBGRAUp := nil;
  FBGRADown := nil;
  FBGRADisabled := nil;
  FBGRAHot := nil;

How it works : GetPtrBitmap returns a pointer to the TBmp. The result is thus valid until TBmp is freed. Horizontal slices of bitmaps have the same format that the whole bitmap, so there is no need to copy it.

About fading : you may consider drawing a fading effect that is a transition between two bitmaps by using a temporary bitmap, drawing first bitmap with dmSet and second bitmap with dmSet and opacity. Finally to draw the temporary bitmap.

What you do here is a superposition, which means that if the second bitmap has transparent parts, these parts will still show the underlying bitmap. But this is cool if you want to do a glowing effect.

See what I mean ?
Title: Re: BGRABitmap tutorial
Post by: circular on December 11, 2011, 02:26:24 pm
In fact, it seems that the error I found in BGRABitmap is causing the error you mentionned. Anyway here is a new version of BGRABitmap (5.5) :
- new blend operations : boNiceGlow and boDarkOverlay
- merged boMultiply and boLinearMultiply because it looked the same
- css colors : CSSBlue, CSSRed etc.
- TBGRAColorList : CSSColors.ByName[...]
- StrToBGRA handles CSS color names
- alpha PutImage fix

http://sourceforge.net/projects/lazpaint/files/src/
Title: Re: BGRABitmap tutorial
Post by: lainz on December 11, 2011, 02:34:06 pm
In fact, it seems that the error I found in BGRABitmap is causing the error you mentionned. Anyway here is a new version of BGRABitmap (5.5) :
- new blend operations : boNiceGlow and boDarkOverlay
- merged boMultiply and boLinearMultiply because it looked the same
- css colors : CSSBlue, CSSRed etc.
- TBGRAColorList : CSSColors.ByName[...]
- StrToBGRA handles CSS color names
- alpha PutImage fix

http://sourceforge.net/projects/lazpaint/files/src/

You're the best  :D
Title: Re: BGRABitmap tutorial
Post by: circular on December 11, 2011, 05:31:30 pm
lol if I am only compared with myself, yes I am the best   :D
Title: Re: BGRABitmap tutorial
Post by: lainz on December 11, 2011, 06:03:45 pm
 ::)

well comparing circular with Johann you're the best  :D
Title: Re: BGRABitmap tutorial
Post by: circular on December 11, 2011, 06:16:11 pm
Yes. Johann >= circular because Johann = circular
lol
Title: Re: BGRABitmap tutorial
Post by: lainz on December 18, 2011, 12:04:17 am
There is a memory leak in bgrabitmaptypes. see attached pic.
Title: Re: BGRABitmap tutorial
Post by: circular on December 19, 2011, 10:36:50 am
Yes I know. It's fixed on subversion.
Title: Re: BGRABitmap tutorial
Post by: Khelle on December 25, 2011, 12:14:41 pm
Is there any way to use graphics created by BGRABitmap as a cursor image?
And if there is, how can I do it?
Title: Re: BGRABitmap tutorial
Post by: circular on December 25, 2011, 03:04:27 pm
There is no function in BGRABitmap to do this explicitely. Maybe it would be possible by creating a stream with CUR file format, and then load from this stream. It would be necessary to know CUR file format to do so.
Title: Re: BGRABitmap tutorial
Post by: Khelle on December 27, 2011, 07:34:33 pm
Ok, I understand but there should be a function to use some graphics, as cursor.
For example in CSS we have:
cursor: url(...), default;

Is there something like that in lazarus? I would like to be able to use bitmap created by TBGRABitmap or simply graphic file like .png or .jpg?
Title: Re: BGRABitmap tutorial
Post by: circular on December 28, 2011, 08:47:53 am
I totally understand your question, but I don't know the answer. Can someone help here ?
Title: Re: BGRABitmap tutorial
Post by: lainz on December 28, 2011, 05:20:46 pm
I've seen in some post that Lazarus has an object to manage the cursor, search in the forum.
Title: Re: BGRABitmap tutorial
Post by: lainz on January 12, 2012, 03:23:27 pm
I've commited a fix loading bgrapixel from string, the function StrToBGRA when the string is something like 'rgba(80,70,60,50);'

before it always returned alpha as 255, now it works fine.
Title: Re: BGRABitmap tutorial
Post by: lainz on January 16, 2012, 01:10:45 am
I've commited a fix loading bgrapixel from string, the function StrToBGRA when the string is something like 'rgba(80,70,60,50);'

before it always returned alpha as 255, now it works fine.

I've reverted the fix. Is the normal CSS behavior.
Title: Re: BGRABitmap tutorial
Post by: tomek on January 23, 2012, 10:14:13 pm
Is there any function in BGRABitmap to draw "Tilted ellipse" (with angle used to tilt the ellipse) ?
If not, can someone point me how to draw that ellipse?
Title: Re: BGRABitmap tutorial
Post by: circular on January 24, 2012, 07:29:56 pm
You can do this with Canvas2D property. Use scale, rotate, translate, arc and stroke. Finally call resetTransform for next drawing. You can also start with save (state) and end with restore (state).

EDIT: also call beginPath before arc, so the complete sequence is :

scale, rotate, translate, beginPath, arc, stroke, resetTransform
Title: Re: BGRABitmap tutorial
Post by: tomek on January 24, 2012, 11:34:40 pm
You can do this with Canvas2D property. Use scale, rotate, translate, arc and stroke. Finally call resetTransform for next drawing. You can also start with save (state) and end with restore (state).

EDIT: also call beginPath before arc, so the complete sequence is :

scale, rotate, translate, beginPath, arc, stroke, resetTransform

Thanks.
I was thinking about the real draw tilted ellipse, but you're right, it will be much easier with rotate Canvas2D.  :) Thanks.

Title: Re: BGRABitmap tutorial
Post by: circular on January 25, 2012, 03:44:26 pm
You're welcome.  :)
Title: Re: BGRABitmap tutorial
Post by: circular on February 19, 2012, 10:58:20 pm
Here is a new version of BGRABitmap (5.6) with :
- text functions can have floating point coordinates for (x,y)
- there is a ClearTypeDrawPixel function in BGRABlend so you can create your own drawing routines using ClearType (you need to supply the clearType intensity for each channel)

And new color functions :
- BGRADiff now returns a better estimation of the difference of color perceived by a human observer
- BGRAWordDiff does the same with a better accuracy
- ExpandedDiff returns the difference with TExpandedPixels
- GSBAToBGRA computes a color using corrected hue (G instead of H), saturation and brightness (instead of lightness). The same record as HSLA is used but interpreted differently.
- HtoG and GtoH function to convert to/from corrected hue

The standard hue H is a number between 0-65535 where each of the six primary color has the same importance (65536/6). The corrected hue is also a number between 0-65535, but the ranges are not equal to reflect that fact for example that many colors between red and yellow are perceived, where as few colors are perceived between yellow and green for example.

The standard lightness L is a number between 0-65535 that has two different meanings. From 0 to 32768 it is a gradient from black to bright color, and from 32768 to 65535 is a gradient from bright color to white. The brightness B is a also a number between 0-65535, but has always the same meaning : the real preception of brightness. So for some color, the pure color will be with L = 32768 but not with B = 32768. The parameter B = 32768 will mean an average brightness.

Here is an example of gradient using GSBA color.

Title: Re: BGRABitmap tutorial
Post by: circular on March 05, 2012, 03:49:35 pm
Hi folks.

Here is a new version of BGRABitmap (5.7). There are major improvements in 3D rendering. More code is stored in inc files in order to increase code flexibility.

What's new in existing units :
- ScanAtInteger function : for fast non interpolated texture mapping
- ConvertToLinearRGB or FromLinearRGB : this is a lossy conversion, but can be useful, for example if you get RGB data that is supposed to be linear, or if you are working with masks
- more color conversion routines like BGRAToGSBA
- TBGRAHueGradient to draw easily rainbow-like gradients. Options are provided to have constant intensity gradients (while hue changes) and to have a more natural distance between hues.
- new polygon filling routines : linear color, perspective color, zbuffer, shaders, SSE optimisation (in BGRAPolygonAliased unit and used by Scene3d)

With 3D :
- materials (specular index, light through factor)
- SeparatePart (to rotate a part independently from the rest of an object)
- lighting optimisation
- CreateSphere and HalfSphere (polygonal)
- no more phong light object : now specular index is defined with materials so you can have some part of the object the reflects light and another part that does not
- bounding box function
- vertex computing optimisation
- vertices renamed to MainPart so it is obvious there can be subparts
- new examples in bgratutorial3D folder
- RenderingOptions variable to quickly define how you want the scene to be renderd

New units :
- BGRAColorInt to handle colors stored linearly as integers (longint) where 65536 equals full lightness. You can thus compute values that are above maximum values (above 65536 and under 0)
- BGRAMatrix3D : matrix are available as a separate unit
- BGRASSE : provides 3D coordinates stored as 128 bit, providing SSE optimisation if available (SSE 1,2,3)

Available at:
http://sourceforge.net/projects/lazpaint/files/src/

Here is a screenshot of 3d rendering
Title: Re: BGRABitmap tutorial
Post by: lainz on March 05, 2012, 04:37:57 pm
I get invalid filename in Ex4.

BTW nice 3D is really much faster now.
Title: Re: BGRABitmap tutorial
Post by: circular on March 05, 2012, 04:50:42 pm
There is an "obj" directory, you need to copy it near the exe file (in lib directory).
Title: Re: BGRABitmap tutorial
Post by: lainz on March 07, 2012, 02:42:03 pm
There is an "obj" directory, you need to copy it near the exe file (in lib directory).

I see LOL
Title: Re: BGRABitmap tutorial
Post by: fenix on May 29, 2012, 03:05:29 pm
I have a big BGRABitmap image. And have to move it on the part of the screen (about 80% of the screen). What is the best technique to do it?
Title: Re: BGRABitmap tutorial
Post by: circular on May 31, 2012, 01:30:49 am
You mean it must be clipped ?

If you draw it on a virtual screen, i.e. a temporary bitmap before drawing, then you can specify a ClipRect if it is only for a portion of the destination bitmap, and then call PutImage with the offset you want.
Title: Re: BGRABitmap tutorial
Post by: circular on June 13, 2012, 04:49:08 pm
New version of BGRABitmap (5.7.2).

- added PutImagePart to directly put only a rectangle of a bitmap
- added MergeBGRAWithGammaCorrection to merge two colors taking gamma correction into account
- fix for PutImage with dmSet mode and alpha <> 255
- added CopyRect(X,Y: Integer; SrcBitmap: TBGRACustomBitmap; SrcRect: TRect) in BGRACanvas
- compressable bitmap can now be streamed (read/write) and compression level can be set
- MakeBitmapCopy now accept system colors
- BGRALayers optimization for alpha = 0
- bug fix for QT implementation of drawing
- fix for conflicting case of rendering mode in BGRAScene3D (multishape+zbuffer is not possible)
- BGRASSE optimization
- bug fix for texture rendering with SSE
Title: Re: BGRABitmap tutorial
Post by: circular on July 28, 2012, 10:26:29 pm
Two news :

- New version 5.9 is compatible again with MacOS.
- Here is a tutorial on how to convert an application from TCanvas to TBGRACanvas : http://youtu.be/HGYSLgtYx-U
Title: Re: BGRABitmap tutorial
Post by: circular on September 24, 2012, 05:04:30 pm
New version of BGRABitmap 6.0

The big difference is better layer support and reading/writing of OpenRaster layered images. OpenRaster files can now also be loaded using standard LoadFromFile.

- pixelwise DrawLineAntialias with dashpos, and now DrawPolyLineAntialias looks nice with pixelwise dashes
- Compute ellipse, arc etc. with optional quality parameter (=1 by default meaning approximately one PointF per pixel)
-ComputeEllipse is deprecated, instead use ComputeEllipseBorder and ComputeEllipseContour
more precise and more optimized gradients
- filter emboss highlight with offset (only the portion containing the selection is computed)
- layers have now a unique id
- new layered bitmap functions : SetLayerBitmap, RotateCW, RotateCCW, HorizontalFlip, VerticalFlip, Resample, GetLayerIndexFromId, Duplicate, LayerUniqueId property
- OpenRaster can be loaded from a stream and provides an FPCustomImageReader

How to read an OpenRaster file :
Code: [Select]
uses BGRALayers;

var image: TBGRALayeredBitmap;
begin
  image := TBGRALayeredBitmap;
  image.LoadFromFile('someimage.ora');  //note that you can also load a Paint.NET file here
  ...
  image.Draw(Canvas, 0,0);
  ...
  image.Free;
end;

How to create an OpenRaster file :
Code: [Select]
var image: TBGRALayeredBitmap;
begin
  image := TBGRALayeredBitmap.Create(800,600);
  image.AddOwnedLayer(TBGRABitmap.Create(800,600));
  image.AddLayerFromFile('someimage.png');
  ...
  image.SaveToFile('myimage.ora');
  image.Free;
end;
Title: Re: BGRABitmap tutorial
Post by: circular on September 24, 2012, 08:54:42 pm
I've updated the tutorials.

The welcome page is http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial
It contains now a list of categories to help browse through the tutorials

It does not contain anymore the first tutorial, which is now at
http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_1

Please update the index for german and spanish version :)

Note : I also added sections in tutorials 4 and 5.
Title: Re: BGRABitmap tutorial
Post by: lainz on September 25, 2012, 04:05:37 am
Hi, attached slicescaling, it need your help Circular  ::)

ToDo:
- Fill top, left, right and bottom as texture
- Range check: if you set an invalid integer it just crash
- Things you want to change =)

Enjoy!
Title: Re: BGRABitmap tutorial
Post by: circular on September 25, 2012, 04:14:43 pm
Ok lainz, here is a modified version.

Now you can modify the margins after having created the object with :
Code: [Select]
    procedure SetMargins(AMarginTop, AMarginRight, AMarginBottom, AMarginLeft: integer);
    procedure SetMargins(AMargins: TMargins);
    property Margins: TMargins;

When you draw it, you need to specify the bounding rectangle :
Code: [Select]
    procedure Draw(ABitmap: TBGRABitmap; ARect: TRect; DrawGrid: boolean = False);
    procedure Draw(ABitmap: TBGRABitmap; ALeft,ATop,AWidth,AHeight: integer; DrawGrid: boolean = False);

After loading the bitmap and the margins, you can detect repeat optimizations :
Code: [Select]
    procedure AutodetectRepeat;

In your example, the center of the button can be repeated horizontally, avoiding much resampling. It's faster.

You can modify the repeat options with :
Code: [Select]
    property SliceRepeat[Aposition: TSliceRepeatPosition]: Boolean;
Title: Re: BGRABitmap tutorial
Post by: lainz on September 25, 2012, 05:03:26 pm
Oh well this is really amazing  :'( Thanks  :D

You'll add this to BGRABitmap? Or I'll add it to BGRAControls.. as you wish.
Title: Re: BGRABitmap tutorial
Post by: circular on September 25, 2012, 05:10:27 pm
I hope you like it.  8-)

I don't know where it would be the best place. Probably in BGRAControls, because it's about drawing user controls, right? Or can we use it for something else?
Title: Re: BGRABitmap tutorial
Post by: lainz on September 26, 2012, 01:36:31 am
Ok it's added in BGRAControls.

BTW if you can, add a filter for LazPaint for slice scaling layers.

it will help to create portrait borders for images and photos.

another exAmple: i'm usin 9slice to scale pseudo 3d chart bars in flash. it will be nice to have this in lazpaint, at least as filter..
Title: Re: BGRABitmap tutorial
Post by: Ask on September 26, 2012, 02:06:48 am
The welcome page is http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial
It contains now a list of categories to help browse through the tutorials
also added sections in tutorials 4 and 5.

The category of this page is set to "Graphics/fr" -- probably should be just "Graphics".
Also, you may wish to add "Tutorials" category:
http://wiki.lazarus.freepascal.org/Category:Tutorials (http://wiki.lazarus.freepascal.org/Category:Tutorials)
Title: Re: BGRABitmap tutorial
Post by: circular on September 26, 2012, 11:49:15 am
Good idea.
Title: Re: BGRABitmap tutorial
Post by: lainz on September 28, 2012, 12:34:19 pm
You can helpme with another thing?

It is a multi-9-slice-scaling (an array of bgraslicescaling).

The thing is that the most common used bitmaps has all the stages in the same bitmap distributed horizontal or vertical.

And it's a lazy thing to create each of them individualy from the same or separated bitmaps, there are some controls like checkbox that has 20 stages!

Attached images: Topaz button from AlphaSkins .asz (bmp with grayscale alpha and clFuchsia, i've converted it to png with LazPaint) and Windows 7 Button from the Aero .msstyles.

In bgrabitmapthemeutils i've used the vertical one, but if you can create both it will be nice =)

- It must set the same property for all the objects in the array (fill mode, resample mode, borders, etc..).
- So I can acces them SliceScalingArray[0].Draw(...);

 :-[
Title: Re: BGRABitmap tutorial
Post by: circular on September 28, 2012, 03:13:35 pm
Come on lainz, I'm sure you can do it.

Just create some class TBGRAMultiSlicescaling that you can create with an image, a number of items, and a direction, an that creates (as a private member) an array of TBGRASliceScaling. So you only have to updated those objects when properties are changed.

Finally, define a Draw function, with an additionnal parameter for the number of the item to be slicescaled.

I have confidence that you will do it nicely (and I am a bit tired today).
Title: Re: BGRABitmap tutorial
Post by: lainz on September 28, 2012, 07:49:39 pm
I got it =)

Next I will add 'LoadFromFile' (INI) to speed up the process of creating a drawer.

Edit: added.
Title: Re: BGRABitmap tutorial
Post by: circular on September 29, 2012, 02:50:16 pm
Great !  :)
Title: Re: BGRABitmap tutorial
Post by: circular on October 11, 2012, 05:37:28 pm
New version of BGRABitmap (v6.1)
1) OpenRaster and Paint.NET format not automatically registered.
2) FreeType support added (need Lazarus 1.0)
3) Pixelwise EraseLine and EraseLineAntialias
4) GetDifferenceBounds : compute the area where an image has changed

1) OpenRaster and Paint.NET format are not automatically registered now. It means that if you want to be able to load ORA and PDN files with classic TBitmap.LoadFromFile, you need first to call :
Code: [Select]
uses BGRAOpenRaster, BGRAPaintNET;

begin
  RegisterOpenRasterFormat;
  RegisterPaintNetFormat;
end;

Why ? Because it takes some space. On Windows 64-bit, when BGRABitmap is compiled with optimizations and no debugger info, it takes 536 Ko only, and if you want OpenRaster and Paint.NET format support and call the above procedures, it will be 774 Ko.

Note that those formats are still registered whenever a TPaintDotNetFile or a TBGRAOpenRasterDocument is created.

2) To use FreeType, you need to add EasyLazFreeType and BGRAFreeType units. Here is an example :
Code: [Select]
unit unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
  //units added here
  EasyLazFreeType,             //FreeType support
  BGRABitmap, BGRABitmapTypes, //BGRABitmap
  BGRAFreeType;                //BGRABitmap FreeType support

type

  { TForm1 }

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
    ftfont: TFreeTypeFont;
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  ftfont := TFreeTypeFont.Create;
  ftfont.Name := 'Arial.ttf';
  ftfont.SizeInPixels := 30;
  ftfont.ClearType := True;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  bmp: TBGRABitmap;
  drawer: TBGRAFreeTypeDrawer;
begin
  bmp := TBGRABitmap.Create(ClientWidth,ClientHeight,ColorToRGB(clBtnFace));
  drawer := TBGRAFreeTypeDrawer.Create(bmp);
  drawer.DrawText('Hello world',ftfont,0,0,BGRABlack,[ftaTop,ftaLeft]);
  drawer.Free;
  bmp.Draw(Canvas,0,0);
  bmp.Free;
end;

end.
Title: Re: BGRABitmap tutorial
Post by: circular on October 20, 2012, 12:59:32 pm
New version of BGRABitmap (6.2) with BGRASliceScaling.

http://sourceforge.net/projects/lazpaint/files/src/

How to use it : you can create a TBGRASliceScaling object providing an image and margins and then use the Draw function to draw it on a TBGRABitmap. The SliceRepeat property allows to defined if parts (Top,Bottom,Left,Right,Middle) should be stretched or repeated.

TBGRAMultiSliceScaling does the same, except you provide an image containing multiple images (of different states for example).

See BGRAControls thread (customdrawn_win7) for an example of usage with CustomDrawn controls.
Title: Re: BGRABitmap tutorial
Post by: Osvaldo Arruda on October 20, 2012, 01:45:12 pm
BGRABitmap component (6.2) does not compile/install on Lazarus for Linux 1.0.2

Error:
{$IFDEF LCLgtk2}
type TGtkDeviceContext = TGtk2DeviceContext;
{$ENDIF}   

/home/osvaldo/lazarus/components/bgrabitmap6.2/bgragtkbitmap.pas(70,44) Error: Identifier not found "TGtk2DeviceContext"
/home/osvaldo/lazarus/components/bgrabitmap6.2/bgragtkbitmap.pas(70,44) Error: Error in type definition
/home/osvaldo/lazarus/components/bgrabitmap6.2/bgragtkbitmap.pas(144,5) Error: Illegal type conversion: "HDC" to "TGtkDeviceContext"
/home/osvaldo/lazarus/components/bgrabitmap6.2/bgragtkbitmap.pas(145,5) Error: Illegal type conversion: "HDC" to "TGtkDeviceContext"
/home/osvaldo/lazarus/components/bgrabitmap6.2/bgragtkbitmap.pas(147,5) Error: Illegal type conversion: "HDC" to "TGtkDeviceContext"
/home/osvaldo/lazarus/components/bgrabitmap6.2/bgragtkbitmap.pas(148,5) Error: Illegal type conversion: "HDC" to "TGtkDeviceContext"
/home/osvaldo/lazarus/components/bgrabitmap6.2/bgragtkbitmap.pas(248,10) Error: Illegal type conversion: "HDC" to "TGtkDeviceContext"
/home/osvaldo/lazarus/components/bgrabitmap6.2/bgragtkbitmap.pas(253,25) Error: Illegal type conversion: "HDC" to "TGtkDeviceContext"
/home/osvaldo/lazarus/components/bgrabitmap6.2/bgragtkbitmap.pas(254,5) Error: Illegal type conversion: "HDC" to "TGtkDeviceContext"
/home/osvaldo/lazarus/components/bgrabitmap6.2/bgragtkbitmap.pas(292,5) Error: Illegal type conversion: "HDC" to "TGtkDeviceContext"
/home/osvaldo/lazarus/components/bgrabitmap6.2/bgragtkbitmap.pas(294,5) Error: Illegal type conversion: "HDC" to "TGtkDeviceContext"
/home/osvaldo/lazarus/components/bgrabitmap6.2/bgragtkbitmap.pas(295,5) Error: Illegal type conversion: "HDC" to "TGtkDeviceContext"
/home/osvaldo/lazarus/components/bgrabitmap6.2/bgragtkbitmap.pas(304) Fatal: There were 12 errors compiling module, stopping

 >:(
Title: Re: BGRABitmap tutorial
Post by: circular on October 20, 2012, 02:25:03 pm
Look at this thread and stop complaining
 >:(

http://www.lazarus.freepascal.org/index.php/topic,18618.0.html
Title: Re: BGRABitmap tutorial
Post by: circular on November 01, 2012, 06:41:50 pm
Hello people,

I've added new features (on subversion for now) for vectorization and vectorized fonts.

New units :
- BGRAVectorize unit :
   o VectorizeMonochrome function analyze a black drawing on a white background and transforms it into a poly-polygon
   o TBGRAVectorizedFont class is a typewriter implementation that vectorizes system fonts so you can then draw it and measure all characters
- BGRATypeWriter unit :
   o TBGRACustomTypeWriter provides a skeleton for creating vectorial fonts
   o TBGRAPolygonalGlyph handles polygonal glyphs and can draw them as quadratic curves

Some features added to Canvas2D :
- polylineTo : same as lineTo several times
- toSpline : transform last shape into spline
- fillOverStroke : fill and draw the stroke where there is no fill
- strokeOverFill : stroke and fill the shape where there is no stroke

BGRAText now provides :
- FontEmHeightSign : sign to use for defining the em height in classic TFont object
- FontFullHeightSign : sign to use for defining the full height in a classic TFont object

How to use vectorized font :
Code: [Select]
//supposing you have Bitmap: TBGRABitmap
var vf : TBGRAVectorizedFont;
begin
  vf := TBGRAVectorizedFont.Create;
  vf.Name := 'Times New Roman';
  vf.FullHeight := 50;
  Bitmap.Canvas2D.fillStyle(BGRA(255,0,0,255));
  vf.DrawTextRect(Bitmap.Canvas2D, 'Some text', 0,0);   
  vf.Free;
end;
Note that you should keep TBGRAVectorialFont in memory to avoid loading characters each time you draw text. As you can see, you must use a Canvas2D object. It means that you can apply any effect with the Canvas2D object.

By default, TBGRAVectorialFont simply fills the font, but you can specify various options :
- OutlineMode : what to do exactly, i.e, define a path, stroke, fill, fill and stroke... (font "outline" effect)
- Style : the font style
- ItalicSlope : an italic slope added to the font, whatever the Style property is
- QuadraticCurves : you can deactive quadratic curves for faster rendering
- Orientation : rotation in tenth of degrees
- FontMatrix : any affine matrix transformation
- OnWordBreak : to define your own word breaking handler

More functions :
- DrawTextWordBreak and DrawTextRect : draw text with word break.
- GetTextGlyphBoxes, GetTextWordBreakGlyphBoxes, GetTextRectGlyphBoxes : returns an array of boxes that contains glyphs
- GetTextSize : returns text size (like classic function)
...
Title: Re: BGRABitmap tutorial
Post by: circular on November 05, 2012, 09:43:54 pm
New svn address : svn checkout svn://svn.code.sf.net/p/lazpaint/code/ lazpaint-code
Title: Re: BGRABitmap tutorial
Post by: lainz on November 06, 2012, 02:43:32 am
Ok thanks =)
Title: Re: BGRABitmap tutorial
Post by: circular on January 13, 2013, 11:22:22 pm
Some minor updates on subversion :

- bug fix for blur on 64 bit platform (also faster by the way)
- no need anymore to write GetPixel(integer(...),integer(...)) because added GetPixel(int64,int64)
- optimization of polygon scanning (use TOnePassFillPolyInfo instead of TFillPolyInfo if possible)
Title: Re: BGRABitmap tutorial
Post by: circular on January 17, 2013, 10:46:00 am
New zip version BGRABitmap 6.3 including latest bug fixes and optimizations :

http://sourceforge.net/projects/lazpaint/files/src/
Title: Re: BGRABitmap tutorial
Post by: circular on January 30, 2013, 12:40:13 pm
New version of BGRABitmap 6.4 :
- works with NoGui (you need to use vectorized fonts or freetype fonts in this case)
- vectorized fonts can be saved and loaded
- FontRenderer property added to TBGRABitmap with two possible values : LCL renderer or vectorized font renderer

http://sourceforge.net/projects/lazpaint/files/src/

How to use vectorized font that are saved in *.glyphs files :
Code: [Select]
uses BGRAVectorize;
...
var img: TBGRABitmap;
begin
  ...
  img.FontRenderer := TBGRAVectorizedFontRenderer.Create('.'); //define your directory here

Here is a test project for TAChart and NoGui (http://www.lazarus.freepascal.org/index.php/topic,19721.msg112669.html#msg112669)
Title: Re: BGRABitmap tutorial
Post by: circular on February 01, 2013, 01:31:01 am
New version of BGRABitmap 6.5. This needs latest SVN of units EasyLazFreeType, LazFreeTypeFontCollection and TTCMap of package LazUtils.

There are now 3 rendering methods for text with TBGRABitmap objects:
- using LCL (default, does not work with NoGUI)
- using vectorized fonts (using a fileformat i've made *.glyphs)
- using LazFreeType (using TTF files)

Here is a test program, to test and compare the 3 renders, and generate *.glyphs files :
http://lazarus.johann-elsass.net/fontrendering.zip

LCL is default font rendering. To set to LCL rendering :
Code: [Select]
var bmp: TBGRABitmap;
begin
   ...
   bmp.FontRenderer := nil; //need to do that only if you switched to another renderer before that
end;

To set to vectorized font rendering :
Code: [Select]
uses BGRAVectorize;
...
begin
   bmp.FontRenderer := Bitmap.FontRenderer := TBGRAVectorizedFontRenderer.Create(ExtractFilePath(APath);
where APath is the directory of *.glyphs files.

To set to FreeType rendering :
Code: [Select]
uses BGRAFreeType, LazFreeTypeFontCollection;

var FFreeTypeCollection : TFreeTypeFontCollection;
...
begin
  //create font collection
  FFreeTypeCollection := TFreeTypeFontCollection.Create;
  FFreeTypeCollection.AddFolder(APath);
  //use it in LazFreeType
  SetDefaultFreeTypeFontCollection(FFreeTypeCollection);
  //set the renderer
  bmp := TBGRABitmap.Create(200,200);
  bmp.FontRenderer := TBGRAFreeTypeFontRenderer.Create;

  ...

   bmp.Free;
   SetDefaultFreeTypeFontCollection(nil);
   FFreeTypeCollection.Free;
end;
where APath is a directory containing *.ttf files.
Title: Re: BGRABitmap tutorial
Post by: Silvio Clécio on February 02, 2013, 04:22:51 am
Very nice job buddy!

I'm dreaming day and night to make this possible in Linux. *u*
Title: Re: BGRABitmap tutorial
Post by: circular on February 03, 2013, 04:29:27 pm
Here is yet a new version of BGRABitmap 6.6 :
http://sourceforge.net/projects/lazpaint/files/src/

New font renderer TBGRATextEffectFontRenderer in BGRATextFX, which takes the best out of LCL and vectorized renderer to provide font with :
- any size of text
- text rect and text angle
- outline of any width (filled a single color or a texture)
- text filled with a color or a texture
- drop shadow (any offset, blur size, any color)
- phong shading (does not work with angle)

Here is a sample code :
Code: [Select]
uses BGRABitmap, BGRABitmapTypes, BGRATextFX;

{ TForm1 }

procedure TForm1.FormPaint(Sender: TObject);
var bmp: TBGRABitmap;
  renderer: TBGRATextEffectFontRenderer;
begin
  bmp := TBGRABitmap.Create(ClientWidth,ClientHeight,BGRAWhite);
  renderer := TBGRATextEffectFontRenderer.Create;
  bmp.FontRenderer := renderer;
  renderer.ShadowVisible := True;
  renderer.OutlineVisible := True;
  renderer.OutlineColor := CSSRed;
  renderer.OuterOutlineOnly := True;
  bmp.FontQuality:= fqFineAntialiasing;
  bmp.TextOut(5,5,'Hello world',BGRABlack);
  renderer.OutlineVisible := false;
  bmp.TextOutAngle(5,25,-200, 'Hello world',CSSDarkGreen, taLeftJustify);
  bmp.Draw(Canvas,0,0);
  bmp.Free;
end;   
Title: Re: BGRABitmap tutorial
Post by: circular on February 03, 2013, 04:36:55 pm
Updated test program for font rendering:
http://lazarus.johann-elsass.net/
Title: Re: BGRABitmap tutorial
Post by: circular on February 07, 2013, 10:24:43 am
Here is a tutorial on how to improve TAChart rendering with BGRABitmap :
http://wiki.freepascal.org/BGRABitmap_tutorial_TAChart
Title: Re: BGRABitmap tutorial
Post by: circular on February 17, 2013, 04:40:18 pm
Here is a new version of BGRABitmap (6.7) with some bug fixes and that can be compiled under both Lazarus 1.0 or latest svn :
http://sourceforge.net/projects/lazpaint/files/src/
Title: Re: BGRABitmap tutorial
Post by: lainz on February 17, 2013, 09:35:53 pm
There is any significant difference compiling LazPaint for x64? I've recently installed lazarus svn with i386 and x86_64 support.
Title: Re: BGRABitmap tutorial
Post by: circular on February 17, 2013, 10:42:58 pm
No there is not much difference as far as I know. There could be some optimizations. It may even be slower because SSE optimizations are not activated on 64 bit. On 32 bit, I wrote IFDEF CPUI386 test, but that does not include 64 bit.
Title: Re: BGRABitmap tutorial
Post by: lainz on February 17, 2013, 10:52:41 pm
Ok thanks =)
Title: Re: BGRABitmap tutorial
Post by: circular on February 18, 2013, 11:35:42 am
Here is BGRABitmap v6.8 :
- SSE in 32 and 64 bits
- reverted erroneous ifdef
- sse/float interference fix
- Int32or64 type (it is 32 bit on 32 bit processor and 64 bit on 64 bit processor, so the fastest one)
- less hints

http://sourceforge.net/projects/lazpaint/files/src/
Title: Re: BGRABitmap tutorial
Post by: circular on February 20, 2013, 02:44:21 pm
BGRABitmap v6.9 :
- minor fixes for LazPaint
- TBGRATextEffect return draw bounds
http://sourceforge.net/projects/lazpaint/files/src/
Title: Re: BGRABitmap tutorial
Post by: circular on February 22, 2013, 09:33:49 am
BGRABitmap v6.9.1 :
- nil TextMask fix for BGRAImproveReadability
Title: Re: BGRABitmap tutorial
Post by: idc65 on February 22, 2013, 12:49:52 pm
Hi Circular,
I have upgraded BGRABITMAP and BGRACOntrols to latest version 6.9.1 and 2.0.6. Breviously using 6.2 and 2. I had to update lazarus to latest svn using fpc 2.7.1.

The update seems to have effected all TBCLabel and TBCButton in my project that have the font centralized, the text appears off centered, their is some centering going on but mostly they look as though they are left alligned.

A Similar thing has effected TBGALabel with the addition that the word wrap parameter has defaulted to false, where as in the project they were set to True.

The later is easy to correct, but the centering one is rather odd, as I have tried setting and resetting but still they are not centered.

Title: Re: BGRABitmap tutorial
Post by: circular on February 22, 2013, 01:03:52 pm
Can you post a small test project with that bug?
Title: Re: BGRABitmap tutorial
Post by: idc65 on February 22, 2013, 01:28:05 pm
I have created a sample small proj, and zipped it etc. How do I post or send it.

Just found how to...

zip has res and font used
Title: Re: BGRABitmap tutorial
Post by: lainz on February 22, 2013, 02:15:20 pm
BTW That control is outdated, the same happens with BCLabel and BCButton?
Title: Re: BGRABitmap tutorial
Post by: circular on February 22, 2013, 02:26:07 pm
@idc65:

Thanks, it's fixed on subversion.

EDIT: now published as v6.9.2
Title: Re: BGRABitmap tutorial
Post by: circular on February 26, 2013, 11:34:49 am
New version 6.9.4 :
- interpolation 64-bit fix
- perspective transform options (two planes, outside value)

How to use perspective transform :
Code: [Select]
uses BGRATransform;

var texture, destination: TBGRABitmap;
  perspective : TBGRAPerspectiveScannerTransform;
  quad: array of TPointF;
begin
  ...
  quad := PointsF([ ... ]); //define 4 points here
  perspective := TBGRAPerspectiveScannerTransform.Create(texture,[PointF(-0.5,-0.5),PointF(texture.Width-0.5,-0.5),
          PointF(texture.Width-0.5,texture.Height-0.5),PointF(-0.5,texture.Height-0.5)],quad);
  perspective.IncludeOppositePlane := False; //do not draw opposite plane
  destination.FillRect(0,0,dest.Width,dest.Height,perspective,dmDrawWithTransparency);
  perspective.Free;
Title: Re: BGRABitmap tutorial
Post by: circular on February 26, 2013, 08:33:48 pm
New version 6.9.5 with minor updates :
- filter sharpen with amount parameter (1 = like before)
- stream layers : when loading, can specify to use new layer id's instead of loading them

http://sourceforge.net/projects/lazpaint/files/src/
Title: Re: BGRABitmap tutorial
Post by: lainz on February 26, 2013, 09:35:01 pm
Thankyou!

And please check this  %)
http://lazarus.freepascal.org/index.php/topic,12411.msg115172.html#msg115172
Title: Re: BGRABitmap tutorial
Post by: circular on February 26, 2013, 11:23:34 pm
Thankyou!

And please check this  %)
http://lazarus.freepascal.org/index.php/topic,12411.msg115172.html#msg115172
I don't understand.
Title: Re: BGRABitmap tutorial
Post by: lainz on February 27, 2013, 12:10:11 am
Ok.

Download latest BGRAControls SVN. Open the test_customdrawn_windows 7 project. Compile. It works. Close the application. The heaptrc unit show 'memory heap' (not freed memory)...

I think that the problem is on TBGRAMultiSliceScaling, if I create from a TBGRABitmap it does not free the source object. FBitmapOwned := false;

You can add an option like 'BitmapOwned: Boolean'? Because I need to free the bitmap when the TBGRAMultiSliceScaling is freed.
Title: Re: BGRABitmap tutorial
Post by: circular on February 27, 2013, 10:30:31 am
Ok, it's updated on subversion. Just add a boolean at the end of the Create call :
Code: [Select]
    Result := TBGRAMultiSliceScaling.Create(bmp, ini.ReadInteger(Section, 'MarginTop', 0),
      ini.ReadInteger(Section, 'MarginRight', 0), ini.ReadInteger(Section,
      'MarginBottom', 0), ini.ReadInteger(Section, 'MarginLeft', 0),
      ini.ReadInteger(Section, 'NumberOfItems', 1), Direction, True);
8-)
Title: Re: BGRABitmap tutorial
Post by: lainz on February 27, 2013, 02:02:11 pm
Thanks =) It's nice.
Title: Re: BGRABitmap tutorial
Post by: circular on March 04, 2013, 06:39:40 pm
New version of BGRABitmap (7.0) with :
- more filters can be applied to a rectangle part : FilterSharpen, FilterBlurRadial, FilterBlurMotion, FilterGrayscale, FilterNormalize, FilterTwirl, LinearNegativeRect, NegativeRect
- blur filter tasks that can be put into threads
- slice scaling Owned parameter

How to use blur tasks :
Code: [Select]
uses BGRAFilters;
var task: TFilterTask;
begin
  task := BGRAFilters.CreateMotionBlurTask(bitmap,bounds,distance,angle,oriented);
  task.CheckShouldStop:= @MyCheckShouldStopFunc; //function to tell to stop the task
  try
    Result := task.Execute; //result may not be finished if the task has been stopped
  finally
    task.Free;
  end;
end;
Title: Re: BGRABitmap tutorial
Post by: circular on March 07, 2013, 08:55:51 pm
New version of BGRABitmap (7.1) with :
- Phong lighting vertical position fix
- compilation fix for blur for 32-bit
- TBGRAVectorizedFontRenderer : MaxFontResolution property -> you can use quadratic bezier approximation instead of full vectorization
- TBGRAPolygonalGlyph : Closed and MinimumDotProduct properties -> useful for easy bezier (see below)
- added ComputeEasyBezier in BGRATypeWriter unit -> simply define a polygon and it will be rounded using bezier curves when the dot product is above some value (which means it is not too much of an angle)
- BGRACanvas2D : added CurrentPath property -> you can get the points computed for the current path
- TBGRABitmap : InplaceGrayscale and grayscale task -> so you don't need to allocate a new bitmap to apply grayscale

How to use Easy Bezier :
Code: [Select]
uses BGRABitmap, BGRABitmapTypes, BGRATypewriter;

procedure TForm1.FormPaint(Sender: TObject);
var bmp: TBGRABitmap;
begin
  bmp := TBGRABitmap.Create(ClientWidth,ClientHeight,ColorToRGB(clBtnFace));
  bmp.DrawPolygonAntialias(ComputeEasyBezier(
    [PointF(10,10), PointF(50,10),PointF(90,50),PointF(90,100),PointF(20,100)],
    True, 0.5), BGRABlack, 5);
  bmp.Draw(Canvas,0,0);
  bmp.Free;
end;
Title: Re: BGRABitmap tutorial
Post by: lainz on March 07, 2013, 10:11:47 pm
nice easy bezier!
Title: Re: BGRABitmap tutorial
Post by: idc65 on March 08, 2013, 01:05:45 pm
Help

Just installed version 7.1

Lazarus, compiled and installed, rebuilt but when restarting it just beeps, then exits?
Title: Re: BGRABitmap tutorial
Post by: circular on March 08, 2013, 01:37:43 pm
Strange. Is it 32 bit or 64 bit Lazarus ?

Did you add another package too ?
Title: Re: BGRABitmap tutorial
Post by: idc65 on March 08, 2013, 01:46:43 pm
Hi

32bit on 64bit wndows

No but, i think has something to with the version of bgracontrols 2.0.6, as when it loaded in my project that had controls in it would beep and exit.

So i loaded lazarus.old.exe so that i could create a blank project. then exit. then when I loaded lazarus.exe it started and worked fine, but still would not open my project beep then exit.

So i will go back and use the bgrabitmap 6.9.2 with the bgracontrols 2.0.6 that i had before until I can fathom out where the problem is.

My Project is not using any of the depricated controls bgracontrols.

Title: Re: BGRABitmap tutorial
Post by: lainz on March 08, 2013, 02:11:40 pm
I have Lazarus 32 on Windows 64 and works, maybe the difference is I'm using both packages SVN and Lazarus svn + fpc 2.6.0
Title: Re: BGRABitmap tutorial
Post by: idc65 on March 08, 2013, 02:31:45 pm
Hi

I am using fpc 2.7.1 lazarus 1.1 svn 40362.

When i go back to 6.9.2 all works fine and I can open project, but with 7.1 beep and exit.

It's not a great problem at the moment, As I will continue to use the version that I have

using earlier version of BGACONTROLS as it is going to take lots of work to convert all projects to not use the removed controls.


Title: Re: BGRABitmap tutorial
Post by: Dibo on March 11, 2013, 02:36:01 pm
I can't compile BGRABitmap 7.1 on Linux 64 bit (GTK)
On stable FPC 2.6.0 I get error in unit BGRASSE in line 159 (function Add_AlignedSSE) in asm [dest]:
Quote
Fatal: Internal error 201001032
On FPC 2.7.1 from SVN I get error in BGRABitmapTypes, line 2770 (IntersectLine):
Quote
Fatal: Internal error 2012090607

BTW: I want try BGRA Chart extension: http://wiki.freepascal.org/BGRABitmap_tutorial_TAChart  but don't know where to download this package
Title: Re: BGRABitmap tutorial
Post by: Sternas Stefanos on March 11, 2013, 02:47:02 pm
Temporary solution:
in bgrasse.inc

{$IFDEF MSWINDOWS}  // 9999 for CodeTyphon Studio
  {$IFDEF cpux86_64}
    {$DEFINE BGRASSE_AVAILABLE}
  {$ENDIF}
{$ENDIF}

Title: Re: BGRABitmap tutorial
Post by: Dibo on March 11, 2013, 02:59:40 pm
After this trick, I get another error (FPC 2.6.0):

BGRASSE line 232 "uknown identifer RBX"
Title: Re: BGRABitmap tutorial
Post by: Sternas Stefanos on March 11, 2013, 03:03:26 pm
We use the latest FPC 2.7.1
SVN 10-03-2013 Rev 23788

We test this trick on :
Win32, Win64, Linux32, Linux64, FreeBSD32, FreeBSD64, Solaris32, Solaris64, WinCE, ArchLinux Arm, and Ubuntu Phone OS ...
Title: Re: BGRABitmap tutorial
Post by: circular on March 11, 2013, 05:51:46 pm
Thanks Sternas Stefanos !  :)

BTW: I want try BGRA Chart extension: http://wiki.freepascal.org/BGRABitmap_tutorial_TAChart  but don't know where to download this package
Isn't it available in /components/tachart ?
Title: Re: BGRABitmap tutorial
Post by: Sternas Stefanos on March 11, 2013, 06:32:36 pm
We follow your excellent work Sir
You have our full support and
keep programming...
Title: Re: BGRABitmap tutorial
Post by: Dibo on March 11, 2013, 07:45:49 pm
We use the latest FPC 2.7.1
SVN 10-03-2013 Rev 23788

We test this trick on :
Win32, Win64, Linux32, Linux64, FreeBSD32, FreeBSD64, Solaris32, Solaris64, WinCE, ArchLinux Arm, and Ubuntu Phone OS ...
Well, this trick doesn't work on Code Typhon 4.10 and BGRABitmap 7.1 so I moved back to 6.6.2 included with CT installator
Isn't it available in /components/tachart ?
Thanks. Yes it is. But this package has little mess on Lazarus SVN 40461 (CodeTyphon 4.10). I have finally fixed it. Sternas Stefanos if you are here, you can add this fix to future version of CT:

Necessary files exists in tachart directory but they are not connected to any TAChartX package. So:
- Edit TAChartBGRA package
- Add files taguiconnectorbgra.pas and tabgrautils.pas
- Recompile / reinstall package

After this you will see TChartGUIConnectorBGRA on Chart palette which is needed for this tutorial: http://wiki.freepascal.org/BGRABitmap_tutorial_TAChart

Second thing:
- Code Typhon demo: .../components/tachart/demo/bgra has in project inspector bgrabitmap package requirement instead of pl_bgrabitmap

Third thing:
- See attached image. When use TChartGUIConnectorBGRA in design time, then It looks like negative. But when run application, then everything is ok. Don't know what is a reason. Maybe old bgrabitmap 6.6.2 included in CT? Tested on linux 64 bit XFCE (GTK)
Title: Re: BGRABitmap tutorial
Post by: Sternas Stefanos on March 11, 2013, 09:29:53 pm
Thanks Sir
I will
Title: Re: BGRABitmap tutorial
Post by: Dibo on March 12, 2013, 07:38:40 pm
I'm testing bgrabitmap extension for chart. I noticed two strange things.

First, Chart title property. I'm using BGRA GUI connector for drawing whole chart. If background have standard color like clRed or clBlue then it is ok, but with clForm or clBtnFace I get black background (see first attachment)

Second, 3D chocolate bars. They are drawing ok until I move X axis from left to right (mouse right click + move). They should disappear behind left edge but they are following my move (see screens before and after)

Tested on Linux 64 bit, GTK, BGRABitmap 6.6.2 (from CodeTyphon 4.10)
Title: Re: BGRABitmap tutorial
Post by: circular on March 13, 2013, 12:49:29 am
I'm testing bgrabitmap extension for chart. I noticed two strange things.

First, Chart title property. I'm using BGRA GUI connector for drawing whole chart. If background have standard color like clRed or clBlue then it is ok, but with clForm or clBtnFace I get black background (see first attachment)
Probably a missing ColorToRGB function somewhere in the bgradrawer code.

Quote
Second, 3D chocolate bars. They are drawing ok until I move X axis from left to right (mouse right click + move). They should disappear behind left edge but they are following my move (see screens before and after)
I'm not sure I understand. I'll notify 'ask' about this.
Title: Re: BGRABitmap tutorial
Post by: Dibo on March 13, 2013, 10:16:06 am
Quote
Second, 3D chocolate bars. They are drawing ok until I move X axis from left to right (mouse right click + move). They should disappear behind left edge but they are following my move (see screens before and after)
I'm not sure I understand. I'll notify 'ask' about this.
I'ts hard to explain this behavior :)
Title: Re: BGRABitmap tutorial
Post by: tangentstorm on March 15, 2013, 11:53:08 pm
After this trick, I get another error (FPC 2.6.0):

BGRASSE line 232 "uknown identifer RBX"

This is because free pascal doesn't support Intel assembler syntax for x86_64. (I think because the underlying GNU assembler doesn't support it.)

Changing the $ifdef on lines 230 and 240 to something undefined will make it fall back to the pascal version. Ex:

Code: [Select]
{$ifdef xxxcpux86_64} assembler;
Title: Re: BGRABitmap tutorial
Post by: tangentstorm on March 22, 2013, 10:28:38 pm
Actually, I was mistaken. FPC is able to use intel syntax for 64-bit assembly language after all, as the following test shows. (Run with FPC 2.6.2 on 64-bit Kubuntu 12)

Code: [Select]
{ Move some data from one 64-bit register to another. }
{ This was just to verify that free pascal can indeed }
{ use 64-bit intel assembly language on linux. }

{$asmmode intel}
program asm64;
begin
  asm
    push rax
    pop rbx
  end
end.

If you remove the
Code: [Select]
{$asmmode intel} line, you'll get the "unknown identifier" error.
Title: Re: BGRABitmap tutorial
Post by: Leledumbo on March 22, 2013, 10:51:55 pm
Quote
If you remove the
Code: [Select]
{$asmmode intel}line, you'll get the "unknown identifier" error.
FPC defaults to AT&T syntax for its inline assembler, please read the documentation
Title: Re: BGRABitmap tutorial
Post by: lainz on March 25, 2013, 01:09:33 pm
Hi, in BGRABitmapTypes is defined int32or64 and uint32or64. In systemh.inc there is already defined a solution for this NativeInt and NativeUInt, I think you should use this ones.

Also I've a question, there is a difference on speed using Single, Double or Extended for Real types between 32-64 bit platforms? http://freepascal.org/docs-html/ref/refsu6.html#x28-310003.1.2
Title: Re: BGRABitmap tutorial
Post by: circular on March 25, 2013, 06:52:56 pm
Hi, in BGRABitmapTypes is defined int32or64 and uint32or64. In systemh.inc there is already defined a solution for this NativeInt and NativeUInt, I think you should use this ones.
You're right.

Quote
Also I've a question, there is a difference on speed using Single, Double or Extended for Real types between 32-64 bit platforms? http://freepascal.org/docs-html/ref/refsu6.html#x28-310003.1.2
I suppose Single and Double are about the same speed, and faster than other types. It may depend on the processor of course.

Single also is smaller than Double and can be easily processed with SSE instructions.
Title: Re: BGRABitmap tutorial
Post by: lainz on March 25, 2013, 07:27:33 pm
Quote
Also I've a question, there is a difference on speed using Single, Double or Extended for Real types between 32-64 bit platforms? http://freepascal.org/docs-html/ref/refsu6.html#x28-310003.1.2
I suppose Single and Double are about the same speed, and faster than other types. It may depend on the processor of course.

Single also is smaller than Double and can be easily processed with SSE instructions.

ok thanks.
Title: Re: BGRABitmap tutorial
Post by: martinrame on April 29, 2013, 05:51:18 pm
Hi, I'm trying to compile BgraControls using Lazarus 1.0.8 (SVN 40573) and FPC 2.6.2 for i386-Win32, and I'm getting this error:

Code: [Select]
E:\griensu\bgracontrols\bcfilters.pas(287,10) Error: identifier idents no member "InplaceGrayscale"
Any hint?
Title: Re: BGRABitmap tutorial
Post by: circular on May 04, 2013, 06:12:45 pm
Which version of BGRABitmap are you using?
Title: Re: BGRABitmap tutorial
Post by: Paul_ on May 03, 2015, 02:26:47 pm
Hi,

is there a simple solution how to change BGRABitmap contrast and brightness like in LazPaint  ( menu section: Colors - brightness / contrast) ?
Title: Re: BGRABitmap tutorial
Post by: circular on May 03, 2015, 06:01:59 pm
You can do the following:
Code: [Select]
procedure ChangeLightness(ABitmap: TBGRABitmap; AFactor, AShift: single);
var n: integer;
  p: PBGRAPixel;
  ec: TExpandedPixel;
  curLightness, newLightness: integer;
begin
  p := ABitmap.Data;
  for n := ABitmap.NbPixels-1 downto 0 do
  begin
    ec := GammaExpansion(p^);
    curLightness:= GetLightness(ec);
    newLightness:= round(curLightness*AFactor+AShift*65535);
    if newLightness > 65535 then newLightness:= 65535;
    ec := SetLightness(ec, newLightness, curLightness);
    p^ := GammaCompression(ec);
    inc(p);
  end;
end;
Title: Re: BGRABitmap tutorial
Post by: Paul_ on May 04, 2015, 12:45:21 am
Thank you, it looks good, only I can not go into black / dark.

What should be the range of AFactor and  AShift values ?


Title: Re: BGRABitmap tutorial
Post by: circular on May 04, 2015, 01:47:14 am
With AFactor between 0 and 1, it becomes darker.

Note that if you would like to use a negative value for AShift, then the bounds would be ensured by adding a line:
Code: [Select]
if newLightness < 0 then newLightness := 0;
Title: Re: BGRABitmap tutorial
Post by: Zittergie on August 17, 2015, 10:19:16 pm
Hi,
I am replacing all my images (standard Timage) with bgrabitmaps. Standard Timages give problems on Ubuntu 14.x ARM , wrong or not rendering (giving message: Attempt to draw a drawable with depth 24 to a drawable with depth 32)

I would like to draw on the bitmap to show the anolog VU-meter:

VU-meter:
Code: [Select]
Form1.VuImage.Canvas.Pen.Color:=needle;
Form1.VuImage.Canvas.Pen.Width:=2;
Form1.VuImage.Canvas.Line(94, 94, y, z);

Spectrum Analyzer:
Code: [Select]
if VU_Settings.Active=3 then    // Spectrum Analyser
 begin
   If VU_Settings.Placement=2 then YAxes:= Form1.Panel_VU.Height div 2;
   If VU_Settings.Placement=3 then YAxes:= Form1.Panel_VU.Height-2;
   If VU_Settings.Placement=1 then YAxes:= 2;

   Form1.VuImage.Canvas.Pen.Width:=2;   Form1.VuImage.Canvas.Pen.Color:=clHighlight;
   Form1.VuImage.Canvas.Brush.Style:=bssolid; Form1.VuImage.Canvas.Brush.Color:=clBlack;
   Form1.VuImage.Canvas.Rectangle(0,0,Form1.Panel_VU.Width,Form1.Panel_VU.Height);
   For Counter:=0 to 117 do
   begin
    YValue:=round(MyThread.FFT[counter]*128); YValue2:=YValue;

    Form1.VuImage.Canvas.Pen.Color:=clLime;
    if VU_Settings.Placement=2 then
    begin
      if YValue>38 then YValue:=38;
      Form1.VuImage.Canvas.Line(2+counter*2,YAxes+YValue,round(2+counter*2),YAxes-YValue);
      if YValue2>60 then YValue2:=60;
      Form1.VuImage.Canvas.Pen.Color:=clGreen;
      Form1.VuImage.Canvas.Line(2+counter*2,YAxes+trunc(YValue2/1.8),2+counter*2,yAxes-trunc(YValue2/1.8));
      If VU_Settings.ShowPeaks then
      begin
        Form1.VuImage.Canvas.Pixels[Counter*2+2,YAxes-YValue]:=clRed;
        Form1.VuImage.Canvas.Pixels[Counter*2+3,YAxes-YValue]:=clRed;
      end;
    end;
   if VU_Settings.Placement=3 then
    begin
      if YValue>41 then YValue:=41;
      Form1.VuImage.Canvas.Line(2+counter*2,YAxes,2+counter*2,YAxes-round(YValue*1.8));
      if YValue2>60 then YValue2:=60;
      Form1.VuImage.Canvas.Pen.Color:=clGreen;
      Form1.VuImage.Canvas.Line(2+counter*2,YAxes,2+counter*2,yAxes-trunc(YValue2));
      If VU_Settings.ShowPeaks then
      begin
        Form1.VuImage.Canvas.Pixels[Counter*2+2,YAxes-round(YValue*1.8)]:=clRed;
        Form1.VuImage.Canvas.Pixels[Counter*2+3,YAxes-round(YValue*1.8)]:=clRed;
      end;
    end;
    if VU_Settings.Placement=1 then
    begin
      if YValue>40 then YValue:=40;
      Form1.VuImage.Canvas.Line(2+counter*2,YAxes,2+counter*2,YAxes+round(YValue*1.8));
      if YValue2>70 then YValue2:=70;
      Form1.VuImage.Canvas.Pen.Color:=clGreen;
      Form1.VuImage.Canvas.Line(2+counter*2,YAxes,2+counter*2,yAxes+trunc(YValue2));
      If VU_Settings.ShowPeaks then
      begin
        Form1.VuImage.Canvas.Pixels[Counter*2+2,YAxes+round(YValue*1.8)]:=clRed;
        Form1.VuImage.Canvas.Pixels[Counter*2+3,YAxes+round(YValue*1.8)]:=clRed;
      end;
    end;
   end;
 end;

I tried to translate it to use bgrabitmaps, but without success
Full source:  https://sourceforge.net/p/xixmusicplayer/svn/HEAD/tree/trunk/vuviewer.pas?format=raw (https://sourceforge.net/p/xixmusicplayer/svn/HEAD/tree/trunk/vuviewer.pas?format=raw)
Title: Re: BGRABitmap tutorial
Post by: lainz on August 18, 2015, 05:43:44 am
And how far you reached?

var
  Bitmap: TBGRABitmap;

Bitmap.Canvas --> here you have Canvas.
According to Circular is slower than using Bitmap.(DrawingMethodName) directly.

You need to do it line by line IMO. If you want to do it automatically use Bitmap.Canvas.

For example:
- Pen.Color, Pen.Width are not used in this way in BGRABitmap.

You must use DrawLineAntiAlias and specify parameters like Width and Color in the method directly.

To access pixels:
- There is a faster way that's used for example to make filters.

Code: [Select]
{
// all pixels //
var
  i: integer;
  p: PBGRAPixel;
begin
  p := Bitmap.Data;

  for i := Bitmap.NBPixels-1 downto 0 do
  begin
    p^.red := ;
    p^.green := ;
    p^.blue := ;
    p^.alpha := ;
    Inc(p);
  end;

// scan line //
var
  x, y: integer;
  p: PBGRAPixel;
begin
  for y := 0 to Bitmap.Height - 1 do
  begin
    p := Bitmap.Scanline[y];
    for x := 0 to Bitmap.Width - 1 do
    begin
      p^.red := ;
      p^.green := ;
      p^.blue := ;
      p^.alpha := ;
      Inc(p);
    end;
  end;
  Bitmap.InvalidateBitmap;
}

But you can also use Bitmap.Pixels[x,y]:= TBGRAPixel (like TColor with Alpha).
Title: Re: BGRABitmap tutorial
Post by: aradeonas on August 18, 2015, 07:21:27 am
Zittergie I think you should make it a component from TBGRAVirtualScreen so its easier to control and for play and pause give it a active or pause property,For painting override RedrawBitmapContent like as I done it WallofCovers and paint what you want from the data that it can get from an Event when needed, so you have beautiful and easy to use component .
For painting as 008 said you should probably use TBGRABitmap functions for lines or gradient.
Title: Re: BGRABitmap tutorial
Post by: circular on August 18, 2015, 08:54:03 pm
There is an equivalent for Canvas, it is called CanvasBGRA and provides the same features as Canvas and supports antialiasing.

See : https://www.youtube.com/watch?v=HGYSLgtYx-U
Title: Re: BGRABitmap tutorial
Post by: Carver413 on August 19, 2015, 01:37:02 am
why do you have two canvas ?
Title: Re: BGRABitmap tutorial
Post by: circular on August 19, 2015, 08:12:53 pm
Because Canvas property gives access to the canvas of the system. It is the same as TBitmap.Canvas. There is not much control over how it renders things, it often does not support antialiasing and does not provide transparency. Also it is slower to use it because switching from direct pixel access to the system canvas need some intermediate processing.

CanvasBGRA property uses BGRABitmap functions, and thus provides antialiasing and transparency. It can be used along with direct pixel access without any restriction. So it generally better to use CanvasBGRA.

However, sometimes, it is necessary to use system functions, hence Canvas property is still here. Also it was here before and for backwards compatibility, it is still here.
Title: Re: BGRABitmap tutorial
Post by: scons on August 24, 2016, 12:18:50 pm
Is there a way to start drawing from the middlepoint of a TpaintBox ? To center a drawing ?

Edit: I've found it.
TinyPortal © 2005-2018