Difference between revisions of "BGRABitmap tutorial 2"
(→Run the program: screenshot) |
(Avoid memory leak) |
||
(11 intermediate revisions by 7 users not shown) | |||
Line 1: | Line 1: | ||
+ | {{BGRABitmap_tutorial_2}} | ||
+ | |||
+ | {{BGRABitmap_tutorial_index}} | ||
+ | |||
This tutorial shows you how to load an image and draw it on a form. | This tutorial shows you how to load an image and draw it on a form. | ||
Line 9: | Line 13: | ||
Copy an image into your project directory. Let's suppose it's name is ''image.png''. | Copy an image into your project directory. Let's suppose it's name is ''image.png''. | ||
− | Add a private variable to the main form to store the image : | + | Add a private variable to the main form to store the image: |
− | < | + | |
+ | <syntaxhighlight lang="pascal"> | ||
+ | TForm1 = class(TForm) | ||
private | private | ||
{ private declarations } | { private declarations } | ||
Line 16: | Line 22: | ||
public | public | ||
{ public declarations } | { public declarations } | ||
− | end; </ | + | end; |
+ | </syntaxhighlight> | ||
− | Load the image when the form is created. To do this, double-click on the form, a procedure should appear in the code editor. Add the loading instruction : | + | Load the image when the form is created. To do this, double-click on the form, a procedure should appear in the code editor. Add the following [[TBGRACustomBitmap and IBGRAScanner#Load and save files|loading instruction]] (and don't forget to destroy the image at the end): |
− | < | + | |
+ | <syntaxhighlight lang="pascal"> | ||
+ | procedure TForm1.FormCreate(Sender: TObject); | ||
begin | begin | ||
image := TBGRABitmap.Create('image.png'); | image := TBGRABitmap.Create('image.png'); | ||
− | end; </ | + | end; |
+ | |||
+ | procedure TForm1.FormDestroy(Sender: TObject); | ||
+ | begin | ||
+ | image.Free; | ||
+ | end; | ||
+ | </syntaxhighlight> | ||
=== Draw the bitmap === | === Draw the bitmap === | ||
− | Add an OnPaint handler. To do this, select the main form, then go to the object inspector, in the event tab, and double-click on the OnPaint line. Then, add the drawing code : | + | Add an OnPaint handler. To do this, select the main form, then go to the object inspector, in the event tab, and double-click on the OnPaint line. Then, add the drawing code: |
− | < | + | |
+ | <syntaxhighlight lang="pascal"> | ||
+ | procedure TForm1.FormPaint(Sender: TObject); | ||
begin | begin | ||
image.Draw(Canvas,0,0,True); | image.Draw(Canvas,0,0,True); | ||
− | end; </ | + | end; |
+ | </syntaxhighlight> | ||
Notice that the last parameter is set to True, which means opaque. If you want to take transparent pixels into account, encoded in the alpha channel, you must use False instead. But it can be slow to use transparent drawing on standard canvas, so if it is not necessary, use opaque drawing only. | Notice that the last parameter is set to True, which means opaque. If you want to take transparent pixels into account, encoded in the alpha channel, you must use False instead. But it can be slow to use transparent drawing on standard canvas, so if it is not necessary, use opaque drawing only. | ||
Line 36: | Line 54: | ||
=== Code === | === Code === | ||
− | Finally you should have something like : | + | Finally you should have something like: |
− | < | + | |
+ | <syntaxhighlight lang="pascal"> | ||
+ | unit UMain; | ||
{$mode objfpc}{$H+} | {$mode objfpc}{$H+} | ||
Line 52: | Line 72: | ||
TForm1 = class(TForm) | TForm1 = class(TForm) | ||
procedure FormCreate(Sender: TObject); | procedure FormCreate(Sender: TObject); | ||
+ | procedure FormDestroy(Sender: TObject); | ||
procedure FormPaint(Sender: TObject); | procedure FormPaint(Sender: TObject); | ||
private | private | ||
Line 70: | Line 91: | ||
begin | begin | ||
image := TBGRABitmap.Create('image.png'); | image := TBGRABitmap.Create('image.png'); | ||
+ | end; | ||
+ | |||
+ | procedure TForm1.FormDestroy(Sender: TObject); | ||
+ | begin | ||
+ | image.free; | ||
end; | end; | ||
Line 80: | Line 106: | ||
{$I UMain.lrs} | {$I UMain.lrs} | ||
− | end.</ | + | end. |
+ | </syntaxhighlight> | ||
=== Run the program === | === Run the program === | ||
Line 90: | Line 117: | ||
=== Center the image === | === Center the image === | ||
− | You may want to center the image on the form. To do this, modify the FormPaint procedure : | + | You may want to center the image on the form. To do this, modify the FormPaint procedure: |
− | < | + | |
+ | <syntaxhighlight lang="pascal"> | ||
+ | procedure TForm1.FormPaint(Sender: TObject); | ||
var ImagePos: TPoint; | var ImagePos: TPoint; | ||
begin | begin | ||
Line 102: | Line 131: | ||
image.Draw(Canvas,ImagePos.X,ImagePos.Y,True); | image.Draw(Canvas,ImagePos.X,ImagePos.Y,True); | ||
− | end;</ | + | end; |
+ | </syntaxhighlight> | ||
To compute the position, we need to calculate the space between the image and the left border (X coordinate) and the space between the image and the top border (Y coordinate). The expression ClientWidth - Image.Width returns the available horizontal space, and we divide it by 2 to obtain the left margin. | To compute the position, we need to calculate the space between the image and the left border (X coordinate) and the space between the image and the top border (Y coordinate). The expression ClientWidth - Image.Width returns the available horizontal space, and we divide it by 2 to obtain the left margin. | ||
Line 112: | Line 142: | ||
=== Stretch the image === | === Stretch the image === | ||
− | To stretch the image, we need to create a temporary stretched image : | + | To stretch the image, we need to create a temporary stretched image: |
− | < | + | |
+ | <syntaxhighlight lang="pascal"> | ||
+ | procedure TForm1.FormPaint(Sender: TObject); | ||
var stretched: TBGRABitmap; | var stretched: TBGRABitmap; | ||
begin | begin | ||
Line 119: | Line 151: | ||
stretched.Draw(Canvas,0,0,True); | stretched.Draw(Canvas,0,0,True); | ||
stretched.Free; | stretched.Free; | ||
− | end;</ | + | end; |
+ | </syntaxhighlight> | ||
+ | |||
+ | By default, it uses fine resample, but you can precise if you want to use simple stretch instead (faster): | ||
+ | |||
+ | <syntaxhighlight lang="pascal"> | ||
+ | stretched := image.Resample(ClientWidth, ClientHeight, rmSimpleStretch) as TBGRABitmap; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | You can also specify the interpolation filter with the [[TBGRACustomBitmap and IBGRAScanner#TBGRACustomBitmap|ResampleFilter]] property: | ||
+ | |||
+ | <syntaxhighlight lang="pascal"> | ||
+ | image.ResampleFilter := rfMitchell; | ||
+ | stretched := image.Resample(ClientWidth, ClientHeight) as TBGRABitmap; | ||
+ | </syntaxhighlight> | ||
− | + | [[BGRABitmap tutorial 1|First tutorial]] | [[BGRABitmap tutorial 3|Next tutorial (drawing with the mouse)]] | |
− | |||
− | [[ | + | [[Category:Graphics]] |
+ | [[Category: BGRABitmap]] |
Latest revision as of 19:12, 13 February 2023
│ Deutsch (de) │ English (en) │ español (es) │ français (fr) │ русский (ru) │
Home | Tutorial 1 | Tutorial 2 | Tutorial 3 | Tutorial 4 | Tutorial 5 | Tutorial 6 | Tutorial 7 | Tutorial 8 | Tutorial 9 | Tutorial 10 | Tutorial 11 | Tutorial 12 | Tutorial 13 | Tutorial 14 | Tutorial 15 | Tutorial 16 | Edit
This tutorial shows you how to load an image and draw it on a form.
Create a new project
Create a new project and add a reference to BGRABitmap, the same way as in the first tutorial.
Load the bitmap
Copy an image into your project directory. Let's suppose it's name is image.png.
Add a private variable to the main form to store the image:
TForm1 = class(TForm)
private
{ private declarations }
image: TBGRABitmap;
public
{ public declarations }
end;
Load the image when the form is created. To do this, double-click on the form, a procedure should appear in the code editor. Add the following loading instruction (and don't forget to destroy the image at the end):
procedure TForm1.FormCreate(Sender: TObject);
begin
image := TBGRABitmap.Create('image.png');
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
image.Free;
end;
Draw the bitmap
Add an OnPaint handler. To do this, select the main form, then go to the object inspector, in the event tab, and double-click on the OnPaint line. Then, add the drawing code:
procedure TForm1.FormPaint(Sender: TObject);
begin
image.Draw(Canvas,0,0,True);
end;
Notice that the last parameter is set to True, which means opaque. If you want to take transparent pixels into account, encoded in the alpha channel, you must use False instead. But it can be slow to use transparent drawing on standard canvas, so if it is not necessary, use opaque drawing only.
Code
Finally you should have something like:
unit UMain;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
BGRABitmap, BGRABitmapTypes;
type
{ TForm1 }
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
{ private declarations }
image: TBGRABitmap;
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
image := TBGRABitmap.Create('image.png');
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
image.free;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
image.Draw(Canvas,0,0,True);
end;
initialization
{$I UMain.lrs}
end.
Run the program
You should see a form with an image drawn in it at the upper-left corner.
Center the image
You may want to center the image on the form. To do this, modify the FormPaint procedure:
procedure TForm1.FormPaint(Sender: TObject);
var ImagePos: TPoint;
begin
ImagePos := Point( (ClientWidth - Image.Width) div 2,
(ClientHeight - Image.Height) div 2 );
// test for negative position
if ImagePos.X < 0 then ImagePos.X := 0;
if ImagePos.Y < 0 then ImagePos.Y := 0;
image.Draw(Canvas,ImagePos.X,ImagePos.Y,True);
end;
To compute the position, we need to calculate the space between the image and the left border (X coordinate) and the space between the image and the top border (Y coordinate). The expression ClientWidth - Image.Width returns the available horizontal space, and we divide it by 2 to obtain the left margin.
The result can be negative if the image is bigger than the client width. In this case, the margin is just set to zero.
You can run the program and see if it works. Notice what happens if we remove the test for negative position.
Stretch the image
To stretch the image, we need to create a temporary stretched image:
procedure TForm1.FormPaint(Sender: TObject);
var stretched: TBGRABitmap;
begin
stretched := image.Resample(ClientWidth, ClientHeight) as TBGRABitmap;
stretched.Draw(Canvas,0,0,True);
stretched.Free;
end;
By default, it uses fine resample, but you can precise if you want to use simple stretch instead (faster):
stretched := image.Resample(ClientWidth, ClientHeight, rmSimpleStretch) as TBGRABitmap;
You can also specify the interpolation filter with the ResampleFilter property:
image.ResampleFilter := rfMitchell;
stretched := image.Resample(ClientWidth, ClientHeight) as TBGRABitmap;