Solved

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

Posted on 2010-09-02
18
571 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
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
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
 

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

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Delphi: how to send PJL commands to printer 3 99
Delphi Form ownership 4 89
How to open a new windows chrome resized and disabled the toolbar? 3 113
oracle global variables 4 68
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

770 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