I am using Lazarus and I have a TImage inside a form. The black table is a TImage and the numbers are labels. I need to take a screenshot of the red area I drew.
How can I perform this?
I have Lazarus 1.0.14 and I didn't find any example about this. Any suggestion?
This is a painful design, but well, one simple way might be to put all the controls on a common container and copy its canvas to a bitmap. The following example assumes, that you have put your image and all the labels on a common TPanel control (Panel1):
procedure TForm1.Button1Click(Sender: TObject);
var
R: TRect;
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
try
R := Rect(0, 0, Panel1.Width, Panel1.Height);
Bitmap.SetSize(Panel1.Width, Panel1.Height);
Bitmap.Canvas.CopyRect(R, Panel1.Canvas, R);
Bitmap.SaveToFile('C:\Screenshot.bmp');
finally
Bitmap.Free;
end;
end;
You can use GetFormImage to get the form image, and keep the part that corresponds to your image area in it:
var
Bmp: TBitmap;
begin
Bmp := GetFormImage;
try
Bmp.Canvas.CopyRect(Image1.ClientRect, Bmp.Canvas, Image1.BoundsRect);
Bmp.SetSize(Image1.Width, Image1.Height);
Bmp.SaveToFile('....');
finally
Bmp.Free;
end;
Related
I am using a VCL Application in Delphi. I have a TImage. I want to enlarge the TImage slightly when my cursor is over it. Does anybody know how to do this?
There are many ways.
Personally, I'd create a new custom control specifically for the purpose, so it can be reused.
But if you need a quick version, you can simply use the control's OnMouseEnter and OnMouseLeave events:
procedure TForm1.Image1MouseEnter(Sender: TObject);
var
R: TRect;
begin
R := Image1.BoundsRect;
R.Inflate(6, 6, 6, 6);
Image1.BoundsRect := R;
end;
procedure TForm1.Image1MouseLeave(Sender: TObject);
var
R: TRect;
begin
R := Image1.BoundsRect;
R.Inflate(-6, -6, -6, -6);
Image1.BoundsRect := R;
end;
This is actually more robust than you might think. For instance, if you place the cursor above the image, so that it is enlarged, and then press Ctrl+Alt+Del and move the cursor away, you will find that the image is restored to its original size when you get back to the desktop.
I have a form which I need to print but only a certain section of it and then enlarge it (increase the scale). So far I have the following code:
procedure TForm1.PrintButtonClick(Sender: TObject);
var
printDialog : TPrintDialog;
begin
printDialog := TPrintDialog.Create(Form1);
if printDialog.Execute then
begin
Printer.Orientation := poLandscape; //Better fit than portrait
Form1.PrintScale:=poPrintToFit;
Form1.Print;
end;
end;
However, this prints the whole form. I've googled around and found a few different things that might help but I'm not sure how to use them:
GetFormImage - Is there a way of selecting a specific area with this or does it just take the whole form?
Using a rectangle with given coordinates e.g rectangle1:= rect(Left, Top, Right, Bottom); but then how do I print scale the rectangle to a larger size and print it? As well, seen as though Delphi only gives Left and Top properties, is Right just another name for the furthest left value you want to go to?
UPDATE:
I have tried to create a custom bitmap and then stretch it but I'm not using the strechdraw correctly. It doesn't actually stretch when printed:
procedure TForm1.PrintButtonClick(Sender: TObject);
var
printDialog: TPrintDialog;
Rectangle, stretched: TRect;
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
try
Rectangle := Rect(0, 90, 1450, 780);
stretched := Rect(0, 0, 5000, 3000); //what numbers do i put in here for streching it?
Bitmap.SetSize(Form1.Width, Form1.Height);
Bitmap.Canvas.CopyRect(Rectangle, Form1.Canvas, Rectangle);
Bitmap.Canvas.StretchDraw(stretched, Bitmap); //not sure how to use this
finally
printDialog := TPrintDialog.Create(Form1);
if printDialog.Execute then
begin
with printer do
begin
BeginDoc;
Canvas.Draw(0, 90, Bitmap);
EndDoc;
end;
end;
Bitmap.Free;
end;
end;
Is the try and finally necessary?
When I printed without the stretchdraw it was really small but when I printed with the stretchdraw, a lot of the image was missing so I must be using it wrong
Get rid of your stretched variable and the Bitmap.Canvas.StretchDraw (you can also get rid of the TPrintDialog if you'd like).
// Capture your bitmap content here, and then use this code to scale and print.
Printer.Orientation := poLandscape;
Printer.BeginDoc;
Printer.Canvas.StretchDraw(Rect(0, 0, Printer.PageWidth, Printer.PageHeight), Bitmap);
Printer.EndDoc;
In this question I asked about the correct use of the CopyRect method. I got an answer which fixed my problem, but now the colors of the copied rectangle are wrong (limited to 256 values?).
This is the code:
var
Bmp: TBitmap;
begin
Image1.Picture.LoadFromFile(SomeJPGimage);
Bmp := TBitmap.Create;
try
Bmp.Assign(Image1.Picture.Graphic);
with Bmp do
Image2.Canvas.CopyRect(Image2.Canvas.ClipRect, Canvas, Canvas.ClipRect);
finally
Bmp.Free;
end;
end;
The inset with the false colors is Image2. The colors are right if I don't resize.
How do I get the 24 bit color of the source image (a JPG) when resizing?
edit
Draw is not an alternative; I want to copy a scaled version of part of the source image.
This is not caused because of color reduction, or a wrong pixelformat etc.. You're probably shrinking the image while copying and 'StretchBlt' compresses the image to fit in, and depending on the mode, produces some artifacts. For instance the below 128x128 image
is displayed exactly the same if no resizing is applied. However if it is applied on a 90x100 image for instance, the output is .
You can change the stretching mode for a slightly better result:
var
Bmp: TBitmap;
begin
Image1.Picture.LoadFromFile(SomeJPGimage);
Bmp := TBitmap.Create;
try
Bmp.Assign(Image1.Picture.Graphic);
SetStretchBltMode(Image2.Canvas.Handle, HALFTONE); // <- here
with Bmp do
Image2.Canvas.CopyRect(Image2.Canvas.ClipRect, Canvas, Canvas.ClipRect);
finally
Bmp.Free;
end;
end;
For the above source picture the output now becomes:
(Having browsed a little 'graphics.pas', the VCL seems to be using halftone only for 8-bit images. I may be wrong or right in this assessment, but in any case halftone stretching mode has no such constraint.)
For anything better, I believe, you have to use a proper graphics library.
Edited again:
Turns out the issue is going against the WRONG canvas (too easy with TImage if you're not used to it). Tried to save files on my last sample and got a huge file on the one I assigned. So I Started looking into some of the other values and found that you need to work against the Bitmap Canvas...
var
BMP: TBitmap;
MyClipRect: TRect;
begin
if OpenDialog1.Execute then
begin
Image1.Picture.LoadFromFile(OpenDialog1.FileName);
Bmp := TBitmap.Create;
try
Bmp.Assign(Image1.Picture.Graphic);
myClipRect.Left := (Bmp.Width div 2);
myClipRect.Top := (Bmp.Height div 2);
myClipRect.Right := (Bmp.Width);
myClipRect.Bottom := (Bmp.Height);
with Image2.Picture.Bitmap do
begin
Width := Bmp.Width div 2;
Height := Bmp.Height div 2;
Canvas.CopyRect(Canvas.ClipRect, Bmp.Canvas, MyClipRect);
end;
Image2.Picture.SaveToFile('image2.bmp');
finally
Bmp.Free;
end;
end;
end;
Hope that finally got it. Yeesh.
I draw a list view with OwnerDraw. I need to paint the first column. But I cannot understand how.
I tried:
procedure TFrame6.DownloadListCustomDraw(Sender: TCustomListView;
const ARect: TRect; var DefaultDraw: Boolean);
var
R: TRect;
begin
DefaultDraw := False;
Sender.Canvas.Brush.Color := $F7F7F7;
Sender.Canvas.Brush.Style := bsSolid;
R := ARect;
R.Right := ListView_GetColumnWidth(DownloadList.Handle, DownloadList.Columns[0].Index);
Sender.Canvas.FillRect(R);
DefaultDraw := True;
end;
But I draw over items. How to draw correctly, items and a background?
Thanks!
Summary from comments:
I suggest you to read this delphiDabbler article and hope that it contains enough information to resolve your problem. E.g. Example 1 shows how to change background and Example 4 shows point where item appearance can be changed.
Small tip: don't restore DefaultDraw to True at the end of the handler if you don't want text to be drawn.
I suggest you use VirtualStringTree if you want a lot of customization on the list. Its easy to use and almost anything is possible and most of all freeware. The component can be downloaded at Soft-Gems and few example can be found here
How can I make my program load an image and make it the background for a form?
I need the exact code for it. I've looked all over the internet and the only things I've found are various tweaks and fixes to make backgrounds work as intended in special circumstances. I've also tried some Delphi books I have and I can't find it anywhere.
Put a TImageon your form. Make sure it's behind all other controls on the form. You can right-click it and choose the "send to back" menu option.
Load a graphic.
var
img: TBitmap;
begin
img := TBitmap.Create;
try
img.LoadFromFile('S:\background.bmp');
Assign it to the image control.
Image1.Picture := img;
Clean up.
finally
img.Free;
end;
end;
You can also combine the last three steps to load the graphic and put it in the image control all at once. Thanks to Jon for the suggestion.
Image1.Picture.LoadFromFile('B:\background.bmp');
See also: How to add background images to Delphi forms
What I would do is use the forms OnPaint event, get the canvas (Form1.Canvas), and then use the Draw method (which takes an image) to draw the image you want. Something like the following:
procedure TForm1.FormPaint(Sender: TObject);
var
mypic: TBitMap;
begin
mypic := TBitMap.Create;
try
mypic.LoadFromFile('cant.bmp');
Form1.Canvas.Draw(0, 0, mypic);
finally
FreeAndNil(mypic);
end;
end;
Note that this could be extremely slow.
This is the way all my applications show a form image. I load the image at form creation or when the application calls a specific showing event
var
vDest, vRect: TRect;
begin
vRect := Rect(0, 0, FBackgroundImage.Width, FBackgroundImage.Height);
vDest := Rect(0,0,Self.Width, Self.Height);
Canvas.StretchDraw(vDest, FBackgroundImage);
if FileExists(this) then
FBackgroundImage.LoadFromFile(this);
#Brendan
thanks
//from Brendan code;
var
vDest, vRect: TRect;
FBackgroundImage: TGraphic;
begin
FBackgroundImage := image1.Picture.Graphic; //LOAD from invisible image
vRect := Rect(0, 0, FBackgroundImage.Width, FBackgroundImage.Height);
vDest := Rect(0,0,Self.Width, Self.Height);
Canvas.StretchDraw(vDest, FBackgroundImage);
end;