Question blurry Bitmap

RonR

Well-known member
Joined
Nov 23, 2007
Messages
82
Programming Experience
5-10
below is my code for copying an image from a form to send it to the printer.

it works but it tends to be a little blurry when printed. is there anyway to make it sharper???






Bmp = New Bitmap(Me.ClientSize.Width, Me.ClientSize.Height)

Bmp = New Bitmap(800, 500)


Dim G As Graphics = Graphics.FromImage(Bmp)

G.CopyFromScreen(Me.PointToScreen(Me.ClientRectangle.Location), New Point(0, 0), Me.ClientSize)
 
Maintain the Aspect Ratio

Keep in mind, when you are printing, the page is just another drawing surface and you are trying to fit your image within the bounds of that page.

It would be the same as coping an image from one picturebox to anohter, each having different widths and heights. You would need to scale the image to fit within the destination picturebox while maintaining the aspect ratio.

For demonstration, create a new application, add two buttons to the form.
  • buttonSetup
  • buttonPreview

Add the following imports.
VB.NET:
Imports System.Drawing
Imports System.Drawing.Printing

Add the following global variables.
VB.NET:
    Private psd As PageSetupDialog
    Private ppd As PrintPreviewDialog
    Private WithEvents pDoc As PrintDocument
    Private ImageToPrint As Image

In the form Load event, initialize the print objects.
VB.NET:
    Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        pDoc = New PrintDocument
        psd = New PageSetupDialog
        ppd = New PrintPreviewDialog
    End Sub

Use the pageSetup button to select your printer, orientation, and margins.
VB.NET:
    Private Sub buttonSetup_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles buttonSetup.Click
        With psd
            .Document = pDoc
            .PageSettings = pDoc.DefaultPageSettings
        End With

        If psd.ShowDialog = Windows.Forms.DialogResult.OK Then
            pDoc.DefaultPageSettings = psd.PageSettings
        End If
    End Sub

For our demonstration, just select an image file from disk to "print preview".
VB.NET:
    Private Sub ButtonPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonPreview.Click
        Dim ofd As New OpenFileDialog
        ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
        ofd.Multiselect = False
        ofd.Filter = "Image Files|*.jpg;*.gif;*.bmp"
        If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then
            'First step is to snag a copy of the image from disk
            ImageToPrint = Image.FromFile(ofd.FileName)

            ppd.Document = pDoc
            DirectCast(ppd, Form).WindowState = FormWindowState.Maximized
            ppd.ShowDialog()

        End If
    End Sub

Because we declared pDoc "WithEvents", the pDoc.PrintPage will fire when we do a Print Preview. Here is where we take the image we want to print and scale it to fit within the margins while maintaining the aspect ratio.
VB.NET:
    Private Sub pDoc_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles pDoc.PrintPage

        'Determine the printable area based on the page settings
        Dim pSettings As PageSettings = pDoc.DefaultPageSettings
        Dim pOrigin As Point = New Point(pSettings.Margins.Left, pSettings.Margins.Top)
        Dim pSize As Size = New Size(pSettings.PaperSize.Width - (pSettings.Margins.Left + pSettings.Margins.Right), _
                                     pSettings.PaperSize.Height - (pSettings.Margins.Top + pSettings.Margins.Bottom))

        ' If the user selected Landscape mode, swap the printing area height 
        ' and width.
        If pDoc.DefaultPageSettings.Landscape Then
            Dim intTemp As Int32
            intTemp = pSize.Height
            pSize.Height = pSize.Width
            pSize.Width = intTemp
        End If


        'We have to determine the proper scaling based on the available print area to maintain the aspect ratio
        Dim wRatio As Single = pSize.Width / ImageToPrint.Width
        Dim hRatio As Single = pSize.Height / ImageToPrint.Height
        Dim ScaleToWidth As Boolean = False
        Dim ScaleToHeight As Boolean = False
        If wRatio < hRatio Then
            'Scale to the width ratio
            ScaleToWidth = True
        Else
            'Scale to the height ratio
            ScaleToHeight = True
        End If

        Dim sizePrint As Size
        If ImageToPrint.Width < pSize.Width AndAlso ImageToPrint.Height < pSize.Height Then
            sizePrint = New Size(ImageToPrint.Width, ImageToPrint.Height)
        Else
            If ScaleToWidth Then
                sizePrint = New Size(ImageToPrint.Width * wRatio, ImageToPrint.Height * wRatio)
            ElseIf ScaleToHeight Then
                sizePrint = New Size(ImageToPrint.Width * hRatio, ImageToPrint.Height * hRatio)
            End If
        End If

        'Let's center the image just for fun.
        Dim loc As Point
        loc = New Point(pOrigin.X + ((pSize.Width - sizePrint.Width) / 2), pOrigin.Y + ((pSize.Height - sizePrint.Height) / 2))

        e.Graphics.DrawImage(ImageToPrint, New Rectangle(loc, sizePrint))

        'These lines are not needed. Just here to demonstrate the Margin settings.
        Dim penBorder As New Pen(Color.Blue)
        penBorder.DashStyle = Drawing2D.DashStyle.Dash
        e.Graphics.DrawRectangle(penBorder, New Rectangle(pOrigin.X, pOrigin.Y, pSize.Width, pSize.Height))

    End Sub

The important lesson here is to understand how to maintain the aspect ratio of any graphics object you are re-drawing from a source to a new destination.

hth
 
Back
Top