Solved

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

Posted on 2010-09-02
18
575 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
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

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

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…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

830 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