PILを使ってマルチTIFFファイルを各ページの正しいサイズ・向きでプリンタに印刷したい
python3.7にてPILを使ってマルチTIFFファイル(ページごとにサイズと向きが異なる)を指定プリンタに出力するプログラム(下記)を作成したいと思っているのですが、全てのページが最初に指定したサイズと向きになってしまいます。
各ページを適切なサイズと向きになるようにするにはどうすればよいか教えていただけませんでしょうか?
※各ページのサイズと向きは取得できます。StartPage()~EndPage()間にどのように入れたらよいかがわかりません。ページごとにCreateDCするほかないのでしょうか?
pyPrintout.py
import win32print
import win32ui
import win32gui
from PIL import Image, ImageWin
Image.MAX_IMAGE_PIXELS = 20000000000
HORZRES = 8
VERTRES = 10
LOGPIXELSX = 88
LOGPIXELSY = 90
PHYSICALWIDTH = 110
PHYSICALHEIGHT = 111
# PILを使って画像を印刷する
def main(file_name):
# プリンタ名
printer_name = 'FUJI XEROX DocuWide 6057'
# Imageを読み込み
with Image.open(file_name) as src_image:
# ページ数
pages = src_image.n_frames
# プリンタ情報
pHandle = win32print.OpenPrinter(printer_name, {'DesiredAccess': win32print.PRINTER_ALL_ACCESS})
print_processor = win32print.GetPrinter(pHandle, 2)['pPrintProcessor']
attributes = win32print.GetPrinter(pHandle, 2)
devmode = attributes['pDevMode']
# プリンタ設定を書き換え(サイズ)
devmode.FormName = 'A3'
devmode.PaperSize = 8
devmode.PaperWidth = 2970
devmode.PaperLength = 4200
# プリンタ設定を書き換え(向き)
Orientation = 1
if src_image.size[0] > src_image.size[1]:
Orientation = 2
devmode.Orientation = Orientation
# pDevModeを再設定
attributes['pDevMode'] = devmode
win32print.SetPrinter(pHandle, 2, attributes, 0)
# プリンタ設定ダイアログを表示して確認
caption = f'{printer_name} ({file_name} - {pages}pages)'
status = win32print.DocumentProperties(0, pHandle, caption, devmode, devmode, 5)
# OK
if status == 1:
win32print.SetPrinter(pHandle, 2, attributes, 0)
# キャンセル
else:
win32print.ClosePrinter(pHandle)
return 1
win32print.ClosePrinter(pHandle)
# プリンタ出力コンテキスト作成
pDC = win32gui.CreateDC(print_processor, printer_name, devmode)
hDC = win32ui.CreateDCFromHandle(pDC)
hDC.CreatePrinterDC(printer_name)
# プリンタ印刷領域取得
printable_area = hDC.GetDeviceCaps(HORZRES), hDC.GetDeviceCaps(VERTRES)
printer_size = hDC.GetDeviceCaps(PHYSICALWIDTH), hDC.GetDeviceCaps(PHYSICALHEIGHT)
# 印刷スタート
hDC.StartDoc(file_name)
for page in range(pages):
src_image.seek(page)
hDC.StartPage()
dib = ImageWin.Dib(src_image)
# レシオ、スケールを算出
ratios = [1.0 * printable_area[0] / src_image.size[0], 1.0 * printable_area[1] / src_image.size[1]]
scale = min(ratios)
# スケールされたサイズを取得
scaled_width, scaled_height = [int(scale * i) for i in src_image.size]
x1 = int((printer_size[0] - scaled_width) / 2)
y1 = int((printer_size[1] - scaled_height) / 2)
x2 = x1 + scaled_width
y2 = y1 + scaled_height
# ページをプリンタに出力
dib.draw(hDC.GetHandleOutput(), (x1, y1, x2, y2))
hDC.EndPage()
# 印刷終了
hDC.EndDoc()
hDC.DeleteDC()
return 0
if __name__ == '__main__':
exit(main('multipage.tif'))
0