canvas + create loyout to print lazarus / 39-Graphics ---------------------------------------------------------------------- nicolas_lazarus · 2010-08-04 00:09 This is my first post in this forum and I hope you understand me because my english is not so good I was looking for some ideas to create a layout to print a number of pictures. To be clear I made a picture. I want to include some jpg inside another jpg. Finally i want to print the resultant image. The number of pictures to include it is depend the size of each jpg picture and it is depend the size of the paper to print. As you can see in the attached picture, the work is related to medical images. Maybe i can use the canvas component but I am not really sure if this is the best option. Please, can someone give me a suggestion ? or some article to read ? Thanks in advance!!! Nicolas ---------------------------------------------------------------------- theo · 2010-08-04 08:00 Use "Printer.Canvas" You need "Uses Printers" and the dependency "Printer4Lazarus". The latter is automatically added to your project, if you drop for ex. a TPrintDialog on the form. ---------------------------------------------------------------------- nicolas_lazarus · 2010-08-04 19:06 Hi Theo, I will take a look to "Printer.Canvas" and "Printer4Lazarus". I need to do a pre-view of the resultant image to send to another application running over the WEB, then i need to send the same image to the printer. So, I guess i can use canvas on a (empty) picture?? to add a few pictures, finally if the users says OK I will send the image to the printer. I will read more and then I will write here again. Thanks! Nicolas ---------------------------------------------------------------------- nicolas_lazarus · 2010-08-07 22:41 Hi all ! I was working trying to resize a bitmap, but it doesn't work. Can someone see what am I doing wrong ? this is the code: Code: [Select]function TPrinterFunctions.resizeBitmap(printer_name: string; Source: TBitmap): TBitmap; var   res: TBitmap;   lwidth, lheight: integer;   destination: TRect; begin   res := TBitmap.Create;   lwidth := getPrinterPageWidth(printer_name) div 2;   lheight := getPrinterPageHeight(printer_name) div 2;   res.Width := lwidth;   res.Height := lheight;   destination.Top := 0;   destination.Left := 0;   destination.Right := lwidth;   destination.Bottom := lheight;   res.Canvas.CopyRect(destination, Source, destination);   res.SaveToFile('C:\Users\Nicolas\Desktop\este\printerjob\afterResize .bmp');   Result := res; end; The original image is (bmp): look at beforeResize.jpg (1024 X 2014) The image after resize it  is(bmp): look at  afterResize.jpg (437 X 616) Hope you can help me ! Thanks in advance ! Nico ---------------------------------------------------------------------- jesusr · 2010-08-08 02:55 Have you checked the lazarus/components/printers/samples/dialog sample?, it shows how to scale one image in order to print it. ---------------------------------------------------------------------- felipemdc · 2010-08-08 12:10 Quote from: nicolas_lazarus on August 08, 2010, 12:41:20 amI was working trying to resize a bitmap, but it doesn't work. ..... Code: [Select]  res.Canvas.CopyRect(destination, Source, destination); If you specify the source rectangle in the same size as the destination rectangle, of course it won't resize anything ... public procedure TCanvas.CopyRect(   const Dest: TRect;   SrcCanvas: TCanvas;   const Source: TRect ); virtual; You should so something like: res.Canvas.CopyRect(destination, Source, Bounds(0, 0, Source.Width, Source.Height)); ---------------------------------------------------------------------- nicolas_lazarus · 2010-08-08 15:50 Jesusr,Felipemdc !  Thanks! The problem it is that I should read more about canvas properties, I am new in lazarus. So ,Felipe I fixed it as you mentioned (adding .canvas to Source): Code: [Select]res.Canvas.CopyRect(destination, Source.canvas,Bounds(0, 0, Source.Width, Source.Height)); so : Code: [Select]function TPrinterFunctions.resizeBitmap(printer_name: string; Source: TBitmap): TBitmap; var   res: TBitmap;   lwidth, lheight: integer;   destination: TRect; begin   res := TBitmap.Create;   lwidth := getPrinterPageWidth(printer_name) div 2;   lheight := getPrinterPageHeight(printer_name) div 2;   res.Width := lwidth;   res.Height := lheight;   res.SaveToFile('C:\Users\Nicolas\Desktop\este\printerjob\before.bmp');   destination.Top := 0;   destination.Left := 0;   destination.Right := lwidth;   destination.Bottom := lheight;   res.Canvas.CopyRect(destination, Source.Canvas, Bounds(0, 0, Source.Width, Source.Height));   res.SaveToFile('C:\Users\Nicolas\Desktop\este\printerjob\afterResize .bmp');   Result := res; end; The result is: original image : beforeResize.bmp (1024 X 2014) (512 X 512 pixels each image) Please, see beforeResize.jpg below resized image : afterResize.bmp (2479 X 3508  pixels as final image to print) Please, see afterResize.jpg below (this last image was captured from the screen due the fact the real one is over the max size allowed to be uploaded) Now I should read more about canvas properties to keep the aspect ratio in the final image to print. I mean, I should resize the image to the max size possible without losing the aspect ratio Jesusr, I am reading about you've posted, thanks. As you can see,(2479 X 3508 pixels) , it is a big bmp, 24MB , because this is what I want to send to the printer. Thanks for help ! Nicolas. ---------------------------------------------------------------------- nicolas_lazarus · 2010-08-08 16:08 Hi all ! I forgot to mention something. Why I am resizing the image and then sending it to print ? May be i can jump one step, working directly with printer..canvas. The idea is send a pre view to the browser, because another part of the proyect runs inside the WEB and needs to  know how the image will be printed. Regards ! ---------------------------------------------------------------------- felipemdc · 2010-08-08 21:00 To keep the aspect ratio just pass the appropriate rectangle sizes to CopyRect. You don't have to use:   destination.Top := 0;   destination.Left := 0;   destination.Right := lwidth;   destination.Bottom := lheight; As the destination. Use instead something like:   if lWidth < lHeight then   begin     destination.Top := 0;     destination.Left := 0;     destination.Right := lwidth;     destination.Bottom := Calculate here the appropriate height which keeps the ratio;   end   else   begin     destination.Top := 0;     destination.Left := 0;     destination.Right := Calculate here width which keeps the ratio;     destination.Bottom := lheight;   end; Simple mathematics can solve this problem. ---------------------------------------------------------------------- garlar27 · 2010-08-09 00:16 To keep proportional a scaled image is easy. You need to divide Width over Height (ProprtionNumber=with/Height) then all you need is to multiply the Height by ProportionNumber to have a proportional Width. A simple Example:    Width = 5    Height = 3    ProportionNumber = With/Height    5 / 3 = 1,6666666666666666666666666666667    PropotionNumber = 1,6666666666666666666666666666667    If you need to fit the image in a place with a Height of 6 then:    6 * 1,6666666666666666666666666666667 = 10    If you need to fit the image in a place with a Width of 10 then:    10 / 1,6666666666666666666666666666667 = 6 You have to be aware of how you took the ProportionNumber because you can calculate it the other way (Height/Width) and have a different number and you will have to use it in other way. Same example but...:    ProportionNumber = 3 / 5    3 / 5 = 0,6    ProportionNumber = 0,6    If you need to fit the image in a place with a Height of 6 then:    6 / 0,6 = 10    If you need to fit the image in a place with a Width of 10 then:    10 * 0,6 = 6 ---------------------------------------------------------------------- garlar27 · 2010-08-09 00:19 AND DON'T FORGET TO ROUND THE NUMBERS!!! ---------------------------------------------------------------------- nicolas_lazarus · 2010-08-09 22:02 Thanks ! I working on it. regards Nicolas