Table of Contents

23.6.2 Printing images

The presented project deals with the display (preview) and printing of images that are saved in an image file. Many of the properties, methods and events of the Printer class are used in this project, which is inextricably linked to the use of the Paint and Draw classes. The program prints images from an image file in colour or greyscale. The margins for the left (20mm) and top edges of the image are currently fixed and the image sizes are only scaled for printing on an A4 sheet (standard) if this is necessary. As there are sophisticated programmes for printing images under Linux, the project presented here is primarily intended to introduce you to suitable procedures for printing images from a Gambas application. The programme is based on the article 'How To Print' on the website http://gambasdoc.org/help/howto/print and implements the instructions given there.

Augentrost

Figure 23.6.2.1: Interface of the print programme - image preview

Printing takes place either immediately on the selected printer or to a file - either in PDF format or in PS format, whereby printing to a PostScript file is preferable:

Drucker

Figure 23.6.2.2: Printout to the FS-1030D printer

PDF-File

Figure 23.6.2.3: Printout to a PDF file

The source text is specified in full and then commented for selected sections in order to supplement the internal comments:

[1] ' Gambas class file
[2] 
[3] Private imgUploaded As Image
[4] Private fPaperNonPrintingLeft As Float
[5] Private fPaperNonPrintingTop As Float
[6] Private fDesktopResolutionProInch As Float = (Desktop.Resolution / 25.4)  
[7] 
[8] Public Sub Form_Open()
[9] 
[10]   FMain.Center
[11]   FMain.Arrangement = Arrange.Vertical
[12]   HBox.Spacing = True 
[13]   btnOpenImage.AutoResize = True
[14]   btnOpenImage.Expand = False
[15]   btnPrintImage.AutoResize = True
[16]   btnPrintImage.Expand = False
[17]   btnPrintImage.Enabled = False
[18]   lblImageResolution.AutoResize = True
[19]   lblImageResolution.Expand = False
[20]   lblImageResolution.Visible = False 
[21]   pSpace.Expand = True ' variabler Zwischenraum
[22]   ScrollArea1.Background = &HEFFFDF&
[23]   ScrollArea1.Expand = True
[24]   togbtnColorModus.Picture = Picture["icon:/16/fill"]
[25]   togbtnColorModus.Tooltip = "FarbModus: Farbdruck"
[26]   printerImage.GrayScale = False
[27]   printerImage.FullPage = False ' Default
[28] 
[29] ' Favourable and tried and tested for test purposes
[30]   printerImage.OutputFile = User.Home &/ "img_print.pdf"
[31]    
[32]   GetNonPrintableArea()
[33]   
[34] End
[35] 
[36] Public Sub btnOpenImage_Click()
[37] 
[38]   Dialog.Title = "Select a picture..."
[39]   Dialog.Filter = ["*.png;*.jpg;*.jpeg;*.gif;*.xpm", "Picture files: "]  
[40]   If Dialog.OpenFile() Then Return  
[41]   
[42]   Try imgUploaded = Image.Load(Dialog.Path) 
[43]   If Error Then
[44]      Message.Error("Error opening the image file!")
[45]      Return
[46]   Endif 
[47] 
[48]   ScrollArea1.ResizeContents(imgUploaded.W, imgUploaded.H)
[49]   ScrollArea1.Refresh
[50]   Wait
[51]   btnPrintImage.Enabled = True
[52]   Label1.Visible = True
[53]   Label1.Text = "Image size: " & imgUploaded.W & " x " & imgUploaded.H & " Pixel"
[54]   
[55] End
[56] 
[57] Public Sub ScrollArea1_Draw()  
[58]   If imgUploaded Then Draw.Image(imgUploaded, - ScrollArea1.ScrollX, - ScrollArea1.ScrollY) 
[59] End
[60] 
[61] Public Sub printerImage_Draw()
[62] 
[63]   Dim iMarginLeft, iMarginTop As Float
[64]   Dim iDruckBreite, iDruckHoehe, iDruckrandLinks, iDruckrandOben As Integer
[65]   Dim imgPrint As Image
[66]   
[67] ' Definition of the print margins left and top with fixed values
[68]   iDruckrandLinks = 20 '-- mm
[69]   iDruckrandOben = 15  '-- mm
[70]   
[71]   If Not imgUploaded Then Return
[72]   imgPrint = imgUploaded
[73]   
[74] ' Switching from landscape format to portrait format when Picture.W > Picture.H
[75]   If imgPrint.Width > imgPrint.Height Then imgPrint = imgPrint.Rotate(Pi(0.5)) 
[76]   
[77] ' Conversion from unit point to unit millimetre
[78]   Paint.Scale(Paint.Width / printerImage.PaperWidth, Paint.Height / printerImage.PaperHeight) 
[79]   
[80]   iMarginLeft = iDruckrandLinks - fPaperNonPrintingLeft '-- mm
[81]   iMarginTop = iDruckrandOben - fPaperNonPrintingTop    '-- mm
[82] 
[83] ' The values used 170mm (width) and 260mm (height) are tried and tested
[84]   If PixelToMillimeter(imgPrint.W) > 170 Then
[85]      iDruckBreite = 170 
[86]      iDruckHoehe = CInt(iDruckBreite * (imgPrint.Height / imgPrint.Width))
[87]      If iDruckHoehe > 260 Then
[88]         iDruckHoehe = 260
[89]         iDruckBreite = CInt(iDruckHoehe / (imgPrint.Height / imgPrint.Width))
[90]      Endif
[91]      Paint.DrawImage(imgPrint, iMarginLeft, iMarginTop, iDruckBreite, iDruckHoehe)
[92]      Return
[93]   Endif
[94]      
[95]   If PixelToMillimeter(imgPrint.H) > 260 Then
[96]      iDruckHoehe = 260
[97]      iDruckBreite = CInt(iDruckHoehe / (imgPrint.Height / imgPrint.Width))
[98]      If iDruckBreite > 170 Then
[99]         iDruckBreite = 170
[100]         iDruckHoehe = CInt(iDruckBreite / (imgPrint.Height / imgPrint.Width))
[101]      Endif 
[102]      Paint.DrawImage(imgPrint, iMarginLeft, iMarginTop, iDruckBreite, iDruckHoehe)
[103]      Return
[104]   Endif
[105] 
[106]   iDruckBreite = PixelToMillimeter(imgPrint.W)
[107]   iDruckHoehe = CInt(iDruckBreite * (imgPrint.Height / imgPrint.Width))
[108]   
[109]   Paint.DrawImage(imgPrint, iMarginLeft, iMarginTop, iDruckBreite, iDruckHoehe)
[110]  
[111] End
[112] 
[113] Public Sub btnPrintImage_Click()
[114] 
[115]   If printerImage.Configure() Then Return
[116] 
[117]   Me.Enabled = False          '-- The form is deactivated
[118]      Inc Application.Busy     '-- The programme no longer accepts any input ...
[119]          printerImage.Print   '-- Printing is started
[120]      Dec Application.Busy     '-- The programme is accepting entries again... 
[121]   Me.Enabled = True           '-- The form is activated
[122] 
[123] End
[124] 
[125] Public Sub togbtnColorModus_Click()
[126] 
[127]   If togbtnColorModus.Picture = Picture["icon:/16/fill"] Then
[128]      togbtnColorModus.Picture = Picture["icon:/16/properties"]
[129]      togbtnColorModus.Tooltip = "FarbModus: Graustufen"
[130]      printerImage.GrayScale = True
[131]   Else
[132]      togbtnColorModus.Tooltip = "FarbModus: Farbe"
[133]      togbtnColorModus.Picture = Picture["icon:/16/fill"]
[134]      printerImage.GrayScale = False
[135]   Endif
[136] 
[137] End
[138] 
[139] Public Sub GetNonPrintableArea()
[140] 
[141]   Dim sResultPath, sResultRow, sResultString As String
[142]   Dim aMatrix As String[]
[143]   Dim iPosition As Integer
[144]   
[145]   Shell "locate -b *.ppd | grep " & printerImage.Name To sResultPath
[146]   Shell "grep '*ImageableArea A4/A4' " & sResultPath To sResultRow
[147] 
[148]   iPosition = InStr(sResultRow, Chr(34))
[149]   sResultString = String.Mid(sResultRow, iPosition + 1, -2)
[150]   aMatrix = Split(sResultString, Chr(32))
[151] ' Non-printable upper paper edge
[152]   fPaperNonPrintingTop = Val(aMatrix[1]) * (25.4 / 72) 
[153] ' Non-printable left paper margin
[154]   fPaperNonPrintingLeft = Val(aMatrix[0]) * (25.4 / 72)
[155]  
[156] End
[157] 
[158] Public Function PixelToMillimeter(iPixel As Integer) As Float  
[159]   Return iPixel / fDesktopResolutionProInch
[160] End
[161] 

23.6.2.1 Supplementary comments

The properties of the form and the components used must be set with particular care so that you get exactly the design of the programme interface that you see in Figure 23.6.2.1. In the project, certain properties of selected components (lines 11-25) are assigned suitable values at runtime:

Komponente HBox

Figure 23.6.2.1.1: Container HBox with 5 components

You should pay attention to the component with the red 1. It is a simple, borderless panel in the background colour of the HBox, which uses the property pSpace.Expand = True to create a variable space between the first two and the last components at program runtime, after the component width of the other 4 components - apart from the button for selecting the print mode (colour or greyscale) - has been automatically adjusted according to the length of the label (plus the width of the inserted icon) using the property Komonente.AutoResize = True.

23.6.2.2 Programme extension

As an extension, you can give the form 2 SpinBoxes (sboxMarginLeft, sboxMarginTop) with reasonable start values and well-chosen minimum and maximum values and insert them into the HBox container in order to be able to set the left and right print margins. The following changes in the source code are then necessary

Public Sub Form_Open()
...
  sboxMarginLeft.MinValue = 15 
  sboxMarginLeft.MaxValue = 50 
  sboxMarginLeft.Value = 20 '-- Start value; unit millimetre
  sboxMarginTop.MinValue = 10 
  sboxMarginTop.MaxValue = 25 
  sboxMarginTop.Value = 15  '-- Start value; unit millimetre
...
End
 
Public Sub printerImage_Draw()
...
  iDruckrandLinks = sboxMarginLeft.Value 
  iDruckrandOben = sboxMarginTop.Value
...
End

23.6.2.3 Download

Project

Download