🖨️

WindowsでPythonから画像を印刷する

に公開

WindowsでPythonからWin32 APIを使用して画像をプリンターで印刷する方法です。

以下の記事の「Single image: use PIL and win32ui」を参考にしています。
https://timgolden.me.uk/python/win32_how_do_i/print.html

pywin32とPllowを使用するので、パッケージをあらかじめインストールしておきます。

$ pip install pywin32 Pillow 

https://pypi.org/project/pywin32/
https://pypi.org/project/pillow/

コマンドライン引数で指定した画像をページ全体に印刷するPythonスクリプトは次のようになります。使用するプリンターはWindowsの設定アプリでBluetoothとデバイス > プリンターとスキャナーから既定に設定したものになります。

print.py
import sys
import win32print
import win32ui
from PIL import Image, ImageWin


# ページの印刷可能領域の幅と高さを取得するためのインデックス
HORZRES = 8
VERTRES = 10

# 物理ページの幅と高さを取得するためのインデックス
PHYSICALWIDTH = 110
PHYSICALHEIGHT = 111

def print_image(image_path):
    # Device Contextを作成
    printer_dc = win32ui.CreateDC()

    # 既定のプリンターのDevice Contextを取得
    printer_dc.CreatePrinterDC()

    # Device Contextからプリンターの情報を取得
    printable_size = printer_dc.GetDeviceCaps(HORZRES), printer_dc.GetDeviceCaps(VERTRES)
    page_size = printer_dc.GetDeviceCaps (PHYSICALWIDTH), printer_dc.GetDeviceCaps(PHYSICALHEIGHT)

    # 画像を開く
    image = Image.open(image_path)

    # 画像を印刷可能領域いっぱいにスケーリングするための倍率を計算
    scale = min([float(printable_size[0]) / image.size[0], float(printable_size[1]) / image.size[1]])

    # スプールを開始する
    printer_dc.StartDoc(image_path)
    # 新しいページを開始する    
    printer_dc.StartPage()

    # 画像をページ中央に印刷可能領域いっぱいまでスケーリングして描画する
    dib = ImageWin.Dib(image)
    print_width = int(scale * image.size[0])
    print_height = int(scale * image.size[1])
    x1 = int((page_size[0] - print_width) / 2)
    y1 = int((page_size[1] - print_height) / 2)
    x2 = x1 + print_width
    y2 = y1 + print_height
    dib.draw(printer_dc.GetHandleOutput(), (x1, y1, x2, y2))

    # ページを終了する
    printer_dc.EndPage()
    # スプールを終了して、印刷を開始する
    printer_dc.EndDoc()
    # Device Contextを削除する
    printer_dc.DeleteDC()

if __name__ == '__main__':
  image_path = sys.argv[1]
  print_image(image_path)

次のように使用します。

$ python print.py image.jpg

GetDeviceCapsメソッドで取得できる値の詳しい情報は以下のページに記述されています。

https://learn.microsoft.com/ja-jp/windows/win32/api/wingdi/nf-wingdi-getdevicecaps

Discussion