Click here to Skip to main content
16,020,447 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi guys, i am printing an image in picturebox. The code in the command button sets it to auto-size the image to fit into my picturebox without distorting or changing its resolution. But then when i try to print it, it just print the original size of the image.Why is that happening? Also, I set the SizeMode in the Properties Tab into CenterImage. But the location of the printed image is always at the TopLeft.

VB
Public Class LOA

    Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
        e.Graphics.DrawImage(PictureBox2.Image, 150, 800)
        e.Graphics.DrawString(Label1.Text, Label1.Font, Brushes.Black, 250, 845)
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Label1.Text = Format(Now, "MMMM d, yyyy h:mm:ss tt")
        Dim PicBoxHeight As Integer
        Dim PicBoxWidth As Integer
        Dim ImageHeight As Integer
        Dim ImageWidth As Integer
        Dim TempImage As Image
        Dim scale_factor As Single
        PictureBox2.SizeMode = PictureBoxSizeMode.CenterImage
        ' Get control size
        PicBoxHeight = PictureBox2.Height
        PicBoxWidth = PictureBox2.Width
        ' Load the image. Change Image.FromFile() to match your code
        TempImage = Image.FromFile("D:\Downloads\SampleInstructorSign.jpg")
        ' Get image size
        ImageHeight = TempImage.Height
        ImageWidth = TempImage.Width
        ' Calculate scale_factor
        scale_factor = 1.0 ' No scaling by default i.e. image fits in the Box
        ' 1) Height
        If ImageHeight > PicBoxHeight Then
            ' Reduce height first
            scale_factor = CSng(PicBoxHeight / ImageHeight)
        End If
        ' 2) Width. Notice, we do know now how much we have to scale down the height
        ' and the scale_factor affects width too
        If (ImageWidth * scale_factor) > PicBoxWidth Then
            ' Scaled width exceeds Box's width, recalculate scale_factor
            scale_factor = CSng(PicBoxWidth / ImageWidth)
        End If
        ' Move image to control for resizing
        PictureBox2.Image = TempImage
        ' Get the source bitmap.
        Dim bm_source As New Bitmap(PictureBox2.Image)
        ' Make a bitmap for the result.
        Dim bm_dest As New Bitmap( _
            CInt(bm_source.Width * scale_factor), _
            CInt(bm_source.Height * scale_factor))
        ' Make a Graphics object for the result Bitmap.
        Dim gr_dest As Graphics = Graphics.FromImage(bm_dest)
        ' Copy the source image into the destination bitmap.
        gr_dest.DrawImage(bm_source, 0, 0, _
            bm_dest.Width + 1, _
            bm_dest.Height + 1)
        ' Display the result.
        PictureBox2.Image = bm_dest

        Try
            PrintPreviewDialog1.Document = PrintDocument1 'PrintPreviewDialog associate with PrintDocument.
            PrintPreviewDialog1.ShowDialog() 'open the print preview
        Catch exp As Exception
            MsgBox("An error occurred while trying to load the " & _
                "document for Print Preview. Make sure you currently have " & _
                "access to a printer. A printer must be connected and " & _
                "accessible for Print Preview to work.", MsgBoxStyle.OkOnly, _
                 Me.Text)
        End Try
    End Sub
End Class
Posted

1 solution

Sample VB code to apply the properties for custom printing:

VB
Imports System.Drawing
Imports System.Reflection
Imports System.Drawing.Printing
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports System.IO

Public Class clsPrinting

    Private printDoc As PrintDocument
    Private printSettings As PrinterSettings
    Private imageFilename As String = ""

    Public Property Preview As Boolean = False
    Public Property Documentname As String = "Untitled document"
    Public Property Landscape As Boolean
        Get
            Return printSettings.DefaultPageSettings.Landscape
        End Get
        Set(value As Boolean)
            printSettings.DefaultPageSettings.Landscape = value
        End Set
    End Property
    Public Sub SetMinimumMargins()
        printSettings.DefaultPageSettings.Margins.Left = CInt(printSettings.DefaultPageSettings.HardMarginX) + 1
        printSettings.DefaultPageSettings.Margins.Top = CInt(printSettings.DefaultPageSettings.HardMarginY) + 1
        printSettings.DefaultPageSettings.Margins.Right = CInt(printSettings.DefaultPageSettings.HardMarginX) + 1
        printSettings.DefaultPageSettings.Margins.Bottom = CInt(printSettings.DefaultPageSettings.HardMarginY) + 1
    End Sub

    Public Sub New()
        MyBase.New()
        printSettings = New PrinterSettings
    End Sub

    Public Function ShowPrintDialog() As Boolean
        Try
            Dim pd As New PrintDialog
            pd.PrinterSettings = printSettings
            If pd.ShowDialog = Windows.Forms.DialogResult.OK Then
                printSettings = pd.PrinterSettings
                Return True
            Else
                Return False
            End If
        Catch ex As Exception
            VizualLib.clsErrorHandling.ThrowException(Me.ToString, MethodBase.GetCurrentMethod().Name, ex.Message)
            Return False
        End Try
    End Function

    ''' <summary>
   ''' Prints an image file to full screen on the selected printer
   ''' </summary>
   ''' <param name="imageFile"></param>
   ''' <remarks></remarks>
   Public Sub PrintImage(ByVal imageFile As String)
        Try
            printDoc = New PrintDocument
            AddHandler printDoc.PrintPage, AddressOf printDoc_PrintImage
            imageFilename = imageFile
            With printDoc
                .PrinterSettings = printSettings
                .DocumentName = _Documentname
                If _Preview Then
                    Dim prv As New PrintPreviewDialog
                    prv.Document = printDoc
                    prv.Width = Screen.PrimaryScreen.WorkingArea.Width
                    prv.Height = Screen.PrimaryScreen.WorkingArea.Height
                    prv.ShowDialog()
                Else
                    .Print()
                End If
            End With
        Catch ex As Exception
            VizualLib.clsErrorHandling.ThrowException(Me.ToString, MethodBase.GetCurrentMethod().Name, ex.Message)
        End Try
    End Sub

    Private Sub printDoc_PrintImage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
        Try
            Dim DpiX As Single = 0, DpiY As Single = 0
            Dim bmp As Bitmap = CType(Bitmap.FromFile(imageFilename), Bitmap)
            Dim imgSizeRatio As Double = bmp.Width / bmp.Height
            Dim printBitmap As Bitmap

            With printSettings.DefaultPageSettings

                Dim pageWidth As Single = .Bounds.Width - .Margins.Left - .Margins.Right
                Dim pageHeight As Single = .Bounds.Height - .Margins.Top - .Margins.Bottom
                Dim pageSizeRatio As Double = 0

                GetImageDPI(imageFilename, DpiX, DpiY)

                pageSizeRatio = (pageWidth / pageHeight)

                If imgSizeRatio > pageSizeRatio Then
                    'scale to image width
                   printBitmap = ResizeImage(bmp, pageWidth / bmp.Width, DpiX, DpiY)
                Else
                    'scale to image height
                   printBitmap = ResizeImage(bmp, pageHeight / bmp.Height, DpiX, DpiY)
                End If
                printBitmap.Save("C:\scratch\outputfile.png", Imaging.ImageFormat.Png)
                e.Graphics.DrawImage(printBitmap, .Margins.Left, .Margins.Top)
            End With

            e.HasMorePages = False
        Catch ex As Exception
            VizualLib.clsErrorHandling.ThrowException(Me.ToString, MethodBase.GetCurrentMethod().Name, ex.Message)
        End Try
    End Sub

    ''' <summary>
   ''' Finds the Dots Per Inch of an Image File
   ''' </summary>
   ''' <param name="filename"></param>
   ''' <param name="dpiX"></param>
   ''' <param name="dpiY"></param>
   ''' <remarks>Returns 96DPI if an error occurs as this is the most common value</remarks>
   Private Sub GetImageDPI(ByVal filename As String, ByRef dpiX As Single, ByRef dpiY As Single)
        Try
            Dim workingImage As Image = Image.FromFile(imageFilename)
            Dim TempImg As Image = New Bitmap(workingImage.Width, workingImage.Height)
            Dim ImageDrawer As Graphics = Graphics.FromImage(TempImg)
            dpiX = ImageDrawer.DpiX
            dpiY = ImageDrawer.DpiY
        Catch ex As Exception
            dpiX = 96
            dpiY = 96
        End Try
    End Sub

    ''' <summary>
   ''' Resizes an image using the specified scaling factor whilst maintaining the images aspect ratio
   ''' </summary>
   ''' <param name="img"></param>
   ''' <param name="scaleFactor"></param>
   ''' <param name="dpiX"></param>
   ''' <param name="dpiY"></param>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Private Function ResizeImage(ByRef img As Bitmap, ByVal scaleFactor As Double, ByVal dpiX As Single, ByVal dpiY As Single) As Bitmap
        Try
            Dim imgDest As New Bitmap(CInt(img.Width * scaleFactor * dpiX / 100), CInt(img.Height * scaleFactor * dpiY / 100))

            ' Make a Graphics object for the result Bitmap.
           Using grDest As Graphics = Graphics.FromImage(imgDest)
                ' Copy the source image into the destination bitmap.
               grDest.DrawImage(img, 0, 0, imgDest.Width, imgDest.Height)
            End Using

            Return imgDest
        Catch ex As Exception
            VizualLib.clsErrorHandling.ThrowException(Me.ToString, MethodBase.GetCurrentMethod().Name, ex.Message)
            Return Nothing
        End Try
    End Function

End Class
 
Share this answer
 
Comments
kimsnap 27-Mar-12 21:40pm    
Hi,
Wow, that answer is long. Thanks!
I have read it and I think this would be the bit that will be my solution
' Make a Graphics object for the result Bitmap.
Using grDest As Graphics = Graphics.FromImage(imgDest)
' Copy the source image into the destination bitmap.
grDest.DrawImage(img, 0, 0, imgDest.Width, imgDest.Height)
End Using


I cant try it right now, but i will later when i get back to my own computer. Thank you. :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900