Solved

How to create an image of a form and save it to a file?

Posted on 2010-09-02
18
567 Views
Last Modified: 2012-05-10
Hi,

How can I create an image of a form and save it to a file?
The height and width must be adjusted so it does not exceed the size of an A4 paper.

The whole idea behind this is to add the image to a report and then send it by e-mail as a PDF.
0
Comment
Question by:Delphiwizard
  • 7
  • 4
  • 3
  • +3
18 Comments
 
LVL 1

Expert Comment

by:Noggin182
ID: 33587992
You could create a new TBitmap, draw the form's canvas onto the TBitmap and then call SaveToFile

I don't have Delpi atm but here is the equilivent in Borland C++

  TRect PaperSize;

  PaperSize.Left = 0;
  PaperSize.Top = 0;
  PaperSize.Right  = ClientWidth;
  PaperSize.Bottom = ClientHeight;

  //Adjust paper size right and bottom here to resize the output as needed

  Graphics::TBitmap *bmp = new Graphics::TBitmap();
  bmp->Width = PaperSize.Right;
  bmp->Height = PaperSize.Bottom;
  bmp->Canvas->CopyRect(PaperSize, Canvas, ClientRect);
  bmp->SaveToFile("test.bmp");

  delete bmp;
0
 
LVL 32

Expert Comment

by:ewangoya
ID: 33588563
There's a function in TCustomForm for getting the forms bitmap

I have not tested this yet but try

function GetFormImage(AForm: TForm): TBitmap;
var
  BitMap: TBitMap;
begin
  AForm.ClientWidth := Trunc(AForm.PixelsPerInch * 8.5);
  AForm.ClientHeight := Trunc(AForm.PixelsPerInch * 11);

0
 
LVL 32

Expert Comment

by:ewangoya
ID: 33588575
 Sorry I hit the enter key by mistake
0
 
LVL 32

Expert Comment

by:ewangoya
ID: 33588586
function GetFormImage(AForm: TForm): TBitmap;
begin
  AForm.ClientWidth := Trunc(AForm.PixelsPerInch * 8.5);
  AForm.ClientHeight := Trunc(AForm.PixelsPerInch * 11);
  Result := AFom.GetFormImage;
end;
0
 
LVL 25

Expert Comment

by:epasquier
ID: 33588681
here is a ScreenShot function that can work in pretty much all situations : form capture (either full or client area), whole screen etc.. depending on the parameters. It puts the results in a TBitmap, which you can use after as you wish (save as file, print in PDF ...)

Var
 BMP:TBitmap;
begin
 BMP:=TBitmap.Create;
 ScreenShot(Form.Handle, BMP, False );
 BMP.SaveToFile( 'File.Bmp' );
 BMP.Free;
end;
procedure ScreenShot(hWin:THandle;destBitmap : TBitmap;ClientArea:Boolean=True);

var

   w,h : integer;

   DC : HDC;

   r : TRect;

begin

 if ClientArea then

  begin

   dc := GetDC(hWin) ;

   GetClientRect(hWin,r);

  end else

  begin

   dc := GetWindowDC(hWin) ;

   GetWindowRect(hWin,r) ;

  end;

 w := r.Right - r.Left;

 h := r.Bottom - r.Top;

 try

  destBitmap.Width := w;

  destBitmap.Height := h;

  BitBlt(destBitmap.Canvas.Handle,

         0,

         0,

         destBitmap.Width,

         destBitmap.Height,

         DC,

         0,

         0,

         SRCCOPY) ;

 finally

  ReleaseDC(hWin, DC) ;

 end;

end;

Open in new window

0
 
LVL 32

Expert Comment

by:ewangoya
ID: 33588711
I got to my delphi. Change the name of the function so it does not conflict with the Forms funtion and use it as follows

function GetFormImageAsBitmap(AForm: TForm): TBitmap;
begin
  AForm.ClientWidth := Trunc(AForm.PixelsPerInch * 8.5);
  AForm.ClientHeight := Trunc(AForm.PixelsPerInch * 11);
  Result := AForm.GetFormImage;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Bitmap: TBitmap;
begin
  Bitmap := GetFormImageAsBitmap(Form2);
  try
    Bitmap.SaveToFile(ExtractFilePath(Application.ExeName) + '\test.bmp');
  finally
    FreeAndNil(Bitmap);
  end;
end;
0
 
LVL 25

Expert Comment

by:epasquier
ID: 33588735
note that the adjustment of a bitmap to a printed size is not made at the capture level but on the print level.
A printer has a much better resolution than a screen, so in fact it is up to you when you print your image, or include it in a word document for example, to set the size the image will take in the printed page.

If you want to print programmatically, you will have to calculate this printed size on the page canvas taking the printing resolution into account.

With what is made your report ? manually ? or with some reporting tool ? if the later, then a Image report component will only need the BMP file, or even could be assigned the captured BMP directly, and will calculate the printing size automatically
0
 
LVL 9

Accepted Solution

by:
Mahdi78 earned 350 total points
ID: 33588788
Try this


procedure TForm1.Button1Click(Sender: TObject);
var
  c: TCanvas;
  r: TRect;
  Bmp: TBitMap;
begin
  c := TCanvas.Create;
  c.Handle := GetWindowDC(Handle);
  Bmp := TBitmap.Create;
  try
    r := Rect(0, 0, Width, Height);
    Bmp.Width := Width;
    Bmp.Height := Height;
    Bmp.Canvas.CopyRect(r, c, r);
    Bmp.SaveToFile(ExtractFilePath(Application.ExeName)+'SnapShot.bmp');
  finally
    ReleaseDC(0, c.Handle);
    c.Free;
    Bmp.Free;
  end;
end;

Open in new window

0
 
LVL 1

Expert Comment

by:Noggin182
ID: 33589286
All these suggestions should work but it depends on how you want to resize your image. Ewangoya's suggestion will actually resize the form which I guess is nit what you wanted.

It might help if you explain how the PDF will be generated so we can understand better what resizing you need. My suggestion will allow you to resize the image itself, the other suggestions will require you to resize the image inside your printing routine.

Btw, If you are creating the PDF from your application then you don't need to save the bitmap to a file first
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 

Author Comment

by:Delphiwizard
ID: 33591554
I'll put the image in a ReportBuilder report.
From that I can easily create a PDF-file.
One thing is clear, the form shouldn't be resized so the image will fit the A4, but the image itself must be resized.
Placing the image into an Image-component TppImage might solve this too, as it supports properties like: Stretch and MaintainAspectRatio
This approach allows me to at some additional content to the report.
So... Get the form's image and somehow transfer it to the reportBuilder report. I checked, but the component cannot LoadFromStream. LoadFromFile is available and LoadFromClipboard.
0
 
LVL 32

Assisted Solution

by:ewangoya
ewangoya earned 150 total points
ID: 33591752
You can get the form image bitmap without resizing the fom

var
  Bitmap: TBitmap;
begin
  Bitmap := Form.GetFormImage
  try
    Bitmap.SaveToFile(ExtractFilePath(Application.ExeName) + '\test.bmp');
  finally
    FreeAndNil(Bitmap);
  end;

you can load Report Builder image as follows
ppImage1: TppImage;

ppImage1.Picture.LoadFromFile('Your file name');



0
 
LVL 32

Assisted Solution

by:ewangoya
ewangoya earned 150 total points
ID: 33591792
If you don't want to save the image to file, you can just assign it to the Picture.Bitmap property

  bitmap := GetFormImage;
  ppImage1.Picture.Bitmap := bitmap;
 
0
 
LVL 1

Expert Comment

by:Noggin182
ID: 33591837
I don't think assigning it a picture of TImage will help with printing to PDF.
Normally you will print to a PDF using TCanvas, in which case it will be easier to use my method for resizing, just change the members of PaperSize to the area on the page you want to print on
0
 
LVL 32

Expert Comment

by:ewangoya
ID: 33592034
@Noggin182:
Assigning to the bitmap property has nothing to do with PDF printing. This simply to trnasfer the bitmap into the Report Builder report, from there on it can be saved as a PDF file.
Similarly, what does writing to the canvas got to do with printing to PDF?

If the author is not going to use ReportBuilder, then he/she still needs some kind of library to convert the image to PDF. The library will not neccessarily use the canvas object directly, you may need to send in the whole bitmap or convert to DIB and send that. Correct me if I'm wrong.
0
 
LVL 1

Expert Comment

by:Noggin182
ID: 33592067
ewangoya: Agreed. Sorry for the oversight, I partially withdraw my last comment. In my experience the ReportBuilder isn't that great for more complicated reports, I've had experience with three PDF libraries and to use each of them you just used a TPrinter and interfaced directly with the canvas.

@delphiwizard: It would help us greatly if you could comment on your end goal and how you generate the PDFs. You should have all the information you need but the better solution will depend on your requirements
0
 
LVL 14

Expert Comment

by:systan
ID: 33592881
>>How to create an image of a form and save it to a file?
I think this question is solved by Mahdi78 and Assisted by some experts.

About the Reportbuilder and PDF,  I think a new post is needed.
0
 

Author Comment

by:Delphiwizard
ID: 33593689
Basiscally I got all the answers I need.
As stated before my goal is to create a PDF-file with a image of the form in it.
ReportBuilder has build-in functionality to print a report directly to a PDF-file, so that is already covered.
As for all your posts:
Some posts are in C++, some are using very simple code and accomplish this task with just a few lines of code, some need more code and a select few only ask for a new post :-)
Here are the results from The Netherlands (stolen fron the Songfestival).
0
 

Author Closing Comment

by:Delphiwizard
ID: 33593700
Thank you all for your help.
Points are given based in first workable solution with does (only) what was asked for.
Like the short version of ewangoya and his suggestion for loading the image directly into the ppImage.
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This video discusses moving either the default database or any database to a new volume.
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now