0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

BitmapをA4サイズにプリントアウトする

Posted at

概要

ユーザーからの要望で今年追加した機能。Formのスクリーンショットを取得する機能と組み合わせ、アプリのButtonクリックでスクリーンショットからプリントアウトまでを行っている。

  • 自分でスクリーンショット取得からプリントアウトまで操作するのは手間である(または方法がわからない)
  • 業務上、画面の状態をプリントアウトして回覧しないといけない

というのが要望の理由であった。

ソースコード

Imports System.Drawing.Printing

''' <summary>
''' プリントクラス
''' </summary>
Public Class Print

    ''' <summary>
    ''' A4サイズ横のピクセル数(100dpi)
    ''' </summary>
    Private Const A4_PIXEL_W_100DPI As Integer = 826

    ''' <summary>
    ''' A4サイズ縦のピクセル数(100dpi)
    ''' </summary>
    Private Const A4_PIXEL_H_100DPI As Integer = 1169

    ''' <summary>
    ''' A4サイズ
    ''' </summary>
    Private ReadOnly A4 As New PaperSize("A4", A4_PIXEL_W_100DPI, A4_PIXEL_H_100DPI)

    ''' <summary>
    ''' 余白の割合
    ''' </summary>
    ''' <remarks>
    ''' 印刷時に端が見切れないように余白を設ける
    ''' 長辺の長さに対し、指定の割合だけ四方につける
    ''' </remarks>
    Private Const MARGIN_RATE As Double = 0.025

    ''' <summary>
    ''' プリントするページ
    ''' </summary>
    Private page As Bitmap = Nothing

    ''' <summary>
    ''' 横向きに印刷するかどうか True:横向きにする False:しない
    ''' </summary>
    Private landscape As Boolean

    ''' <summary>
    ''' プリントイベント
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub pd_PrintPage(sender As Object, e As System.Drawing.Printing.PrintPageEventArgs)
        ' プリントする画像
        Dim printBmp As Bitmap = New Bitmap(page, page.Width, page.Height)

        ' 縦横比は元のまま、印刷サイズに収まるようプリントする画像を拡大縮小する
        Dim printRect As Rectangle = AdjustImageRectangle(A4, landscape, printBmp.Size)

        e.Graphics.DrawImage(printBmp, printRect)

        ' プリントする画像を解放する
        printBmp.Dispose()
    End Sub

    ''' <summary>
    ''' プリント実行
    ''' </summary>
    ''' <param name="bitmap">プリントする画像</param>
    Public Sub Execute(ByVal bitmap As Bitmap)
        ' プリントする画像
        page = bitmap

        ' PrintDocumentオブジェクト作成
        Dim printDocument As PrintDocument = New PrintDocument()

        ' PrintPageイベントハンドラ追加
        AddHandler printDocument.PrintPage, AddressOf pd_PrintPage

        ' 横向きにする
        landscape = True
        printDocument.DefaultPageSettings.Landscape = landscape

        ' 出力サイズはA4のみ
        printDocument.DefaultPageSettings.PaperSize = A4

        ' A4横サイズに縦横比を維持したまま画像が収まるサイズを計算する

        ' PrintControllerプロパティをStandardPrintControllerに
        printDocument.PrintController = New System.Drawing.Printing.StandardPrintController

        ' PrintDialogクラスの作成
        Dim printDialog As PrintDialog = New PrintDialog()

        ' PrintDocumentを指定
        printDialog.Document = printDocument

        ' ダイアログを表示
        If printDialog.ShowDialog() = DialogResult.OK Then
            ' OKボタン選択時に印刷
            printDocument.Print()
        End If
    End Sub

    ''' <summary>
    ''' 画像サイズを調整する
    ''' </summary>
    ''' <param name="paperSize">用紙サイズ</param>
    ''' <param name="landScape">True:横向きが有効 False:無効</param>
    ''' <param name="size">画像サイズ</param>
    ''' <returns></returns>
    ''' <remarks>
    ''' 縦横比を維持したまま用紙に収まるよう拡大縮小する
    ''' 印刷時に端が切れることを考慮し、端に余白を設ける
    ''' </remarks>
    Private Function AdjustImageRectangle(ByVal paperSize As PaperSize, ByVal landScape As Boolean, ByVal size As Size) As Rectangle
        ' 用紙のピクセル数
        Dim paperWidth As Double
        Dim paperHeight As Double

        ' 端に設ける余白のピクセル数
        Dim margin As Double = 0.0

        If landScape = False Then
            ' 縦向きの場合
            paperWidth = CDbl(paperSize.Width)
            paperHeight = CDbl(paperSize.Height)
            margin = paperHeight * MARGIN_RATE
        Else
            ' 横向きの場合
            paperWidth = CDbl(paperSize.Height)
            paperHeight = CDbl(paperSize.Width)
            margin = paperWidth * MARGIN_RATE
        End If

        ' 幅を基準にサイズを計算する
        Dim rate As Double = paperWidth / CDbl(size.Width)
        Dim destWidth As Double = paperWidth
        Dim destHeight As Double = CDbl(size.Height) * rate

        ' 幅を基準に計算して高さ方向が収まらない場合、高さを基準にサイズを計算し直す
        If paperHeight < destHeight Then
            rate = paperHeight / CDbl(size.Height)
            destWidth = CDbl(size.Width) * rate
            destHeight = paperHeight
        End If

        ' 描画開始オフセット
        Dim offsetX As Double = (paperWidth - destWidth) / 2.0
        Dim offsetY As Double = (paperHeight - destHeight) / 2.0

        Return New Rectangle(CInt(offsetX) + margin, CInt(offsetY) + margin, CInt(destWidth) - margin * 2.0, CInt(destHeight) - margin * 2.0)
    End Function
End Class

余談

プリントアウトしたものが回覧され、それをカメラ撮影し生成AIでテキスト化しているユーザーがいると後日発覚。最初にテキスト形式のエクスポート機能を用意すればよかった。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?