none
Printing to Printer (maintaining scale)? RRS feed

  • Question

  • Hello, I have a question I was hoping to get some help on.

    I wrote an application to help me visualize sizes of devices on my screen at scale (I like looking at new phones and stuff, along with rando things like Pi screens. It's hard to get tabs on what 5" at 4:3 looks like, for instance).

    Anyhow, I have a lot of the supporting code already done, but I cannot for the life of me figure out this printing business.

    To start, here's the object that will hold most of the data I need to draw the phone screen/bezels:

         Public Class dev_dossier
        Public monitor_scr As Decimal 'monitor diagonal measurement in inches
        Public monitor_ppi As Decimal 'monitor pixels per inch
        Public dev_scrdiag As Decimal 'device diagonal measurement in inches
        Public dev_x_res As Integer 'device x resolution
        Public dev_y_res As Integer 'device y resolution
        Public dev_ppi As Decimal 'device pixels per inch
        Public dev_scr_w As Decimal 'device screen width in inches
        Public dev_scr_l As Decimal 'device screen length in inches
        Public dev_w As Decimal 'full device width in inches
        Public dev_h As Decimal 'full device length in inches
        Public dev_scr_ratio As Decimal 'device screen ratio

        Public Sub New(ByVal scr_diag As String, ByVal dev_diag As String, ByVal dev_res As String, ByVal dev_size() As Decimal)
            monitor_scr = Math.Round(CType(scr_diag, Decimal), 1)
            monitor_ppi = Math.Sqrt(My.Computer.Screen.Bounds.Width ^ 2 + My.Computer.Screen.Bounds.Height ^ 2) / monitor_scr
            dev_scrdiag = Math.Round(CType(dev_diag, Decimal), 1)

            Dim temp(2) As String
            temp = dev_res.Split("x").ToArray

            dev_x_res = CType(temp(0), Integer)
            dev_y_res = CType(temp(1), Integer)

            dev_ppi = Math.Round(Math.Sqrt(dev_x_res ^ 2 + dev_y_res ^ 2) / dev_diag, 1)
            dev_scr_ratio = dev_x_res / dev_y_res

            dev_scr_w = Math.Sqrt((dev_scrdiag ^ 2 / ((dev_scr_ratio ^ 2) + 1)))
            dev_scr_l = dev_scr_ratio * dev_scr_w


            dev_w = dev_size(0)
            dev_h = dev_size(1)
        End Sub

    What I want to do is the following:

    - Get the print PPI so I can rescale the device for printer paper/some way to set this to a known value

    - Check that this new scale is not too large for the printer paper (unlikely with phones, but possible with say, a tablet)

    - Create the image to print. I already have e.graphics code I should be able to adapt without issue for drawing it on the screen of the computer, so I'm hoping that print offers similar methods.

    My preliminary research suggests it does.

    Of course, the final thing to accomplish is.... actually printing something. I managed to trigger page prints, but they were totally blank, which I'd assume I didn't screw up so badly as to entirely miss the page with drawing the rectangles.

    Thank you for any help! If you want to do an example with the drawing code, basically it's just 2 rectangles one drawn inside another, and then centered in the media they're being portrayed.


    An added bonus would be if anyone could instruct on how to flip the printer to landscape printing (I have code that determines if that has to be done working as well for the screen)

    Thank you for any assistance!

    Friday, October 6, 2017 4:37 AM

Answers

  • This example prints a 1 inch ruler to scale of inches on any printer.

    The printer units are hundredths of an inch so there is no "scaling" needed as its already scale of inches. The windows printer driver will handle the details.

    For the image the photo must be cropped to the edge and rotated for this landscape example and then we print the image in a rectangle of the known size.

    Imports System.Drawing.Printing
    
    Public Class Form5
        Private WithEvents PrintDocument1 As PrintDocument = New PrintDocument
        Private PrintPreviewDialog1 As New PrintPreviewDialog
        Private iphone4img As Image = Image.FromFile("c:\bitmaps\iphone4.jpg")
        Private Sub PrintDocument1_PrintPage(sender As Object, e As PrintPageEventArgs) Handles PrintDocument1.PrintPage
    
            Using p As New Pen(Color.Black, 3),
                    f As New Font("tahoma", 14, FontStyle.Bold),
                    brFill As New SolidBrush(Color.LightGray),
                    brText As New SolidBrush(Color.Black)
    
                'the default printer scale units are 100ths of an inch
                'draw 1" high x 9" long rectangle
                e.Graphics.FillRectangle(brFill, New Rectangle(0, 200, 900, 100))
                e.Graphics.DrawRectangle(p, New Rectangle(0, 200, 900, 100))
    
                'draw the scale ticks every inch and label
                p.Width = 1
                For x As Integer = 100 To 800 Step 100
                    e.Graphics.DrawLine(p, x, 200, x, 225)
                    e.Graphics.DrawString(x.ToString, f, brText, x, 230)
                Next
    
                'draw the image
                'assume 2.42" x 4.67"
                Dim rect As New Rectangle(0, 350, 467, 242)
                e.Graphics.DrawImage(iphone4img, rect)
    
            End Using
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Try
                With PrintDocument1
                    'set origin 0, 0 at upper left of margin
                    .OriginAtMargins = True
                    .DefaultPageSettings.Landscape = True
    
                End With
    
                'show print preview with printdoc
                'click print icon button on print preview to print
                PrintPreviewDialog1.Document = PrintDocument1
                PrintPreviewDialog1.ShowDialog()
    
            Catch ex As Exception
                MsgBox("Problem Printing:" & Chr(13) & ex.Message, MsgBoxStyle.Exclamation)
            End Try
        End Sub
    End Class

    This is the original I used.


    Friday, October 6, 2017 10:42 AM

All replies

  • This example prints a 1 inch ruler to scale of inches on any printer.

    The printer units are hundredths of an inch so there is no "scaling" needed as its already scale of inches. The windows printer driver will handle the details.

    For the image the photo must be cropped to the edge and rotated for this landscape example and then we print the image in a rectangle of the known size.

    Imports System.Drawing.Printing
    
    Public Class Form5
        Private WithEvents PrintDocument1 As PrintDocument = New PrintDocument
        Private PrintPreviewDialog1 As New PrintPreviewDialog
        Private iphone4img As Image = Image.FromFile("c:\bitmaps\iphone4.jpg")
        Private Sub PrintDocument1_PrintPage(sender As Object, e As PrintPageEventArgs) Handles PrintDocument1.PrintPage
    
            Using p As New Pen(Color.Black, 3),
                    f As New Font("tahoma", 14, FontStyle.Bold),
                    brFill As New SolidBrush(Color.LightGray),
                    brText As New SolidBrush(Color.Black)
    
                'the default printer scale units are 100ths of an inch
                'draw 1" high x 9" long rectangle
                e.Graphics.FillRectangle(brFill, New Rectangle(0, 200, 900, 100))
                e.Graphics.DrawRectangle(p, New Rectangle(0, 200, 900, 100))
    
                'draw the scale ticks every inch and label
                p.Width = 1
                For x As Integer = 100 To 800 Step 100
                    e.Graphics.DrawLine(p, x, 200, x, 225)
                    e.Graphics.DrawString(x.ToString, f, brText, x, 230)
                Next
    
                'draw the image
                'assume 2.42" x 4.67"
                Dim rect As New Rectangle(0, 350, 467, 242)
                e.Graphics.DrawImage(iphone4img, rect)
    
            End Using
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Try
                With PrintDocument1
                    'set origin 0, 0 at upper left of margin
                    .OriginAtMargins = True
                    .DefaultPageSettings.Landscape = True
    
                End With
    
                'show print preview with printdoc
                'click print icon button on print preview to print
                PrintPreviewDialog1.Document = PrintDocument1
                PrintPreviewDialog1.ShowDialog()
    
            Catch ex As Exception
                MsgBox("Problem Printing:" & Chr(13) & ex.Message, MsgBoxStyle.Exclamation)
            End Try
        End Sub
    End Class

    This is the original I used.


    Friday, October 6, 2017 10:42 AM
  • Thank you for your help.

    That 0.01" thing was a key part of my issue. I now have it set up to print either 2D (just the front face) or 3D (a net for a rectangle approximating the phone) both to scale.

    Thanks!

    Saturday, October 7, 2017 6:25 AM