python3 使用指定打印机打印横向图像/文件

Geo*_* Sp 4 python windows printing pywin32 python-3.x

我想打印我使用指定打印机在脚本上创建的 pdf 文件(或图像),但该文件是横向的。我尝试过Tim Golden 的 python 打印,但打印错误,大部分图像未打印,或者收到一条错误消息,指出未找到指定的文件。这是错误:“pywintypes.error: (2,\'ShellExecute\',\'系统找不到指定的文件。\')” \n命令是这样的:win32api.ShellExecute(0,“print”,文件名, \'/d:"%s"\' % 打印机名称, ".", 0)。当然是文件名打印机是字符串,打印机名称取自 win32print.EnumPrinters(2,None,1)

\n\n

这是我的打印功能:

\n\n
def programA_printer():\n    global name\n    global printer_name\n    global event2\n    # time.sleep(3)\n    i=0\n    while True:\n        if not event2.is_set():\n            try:\n                img = Image.open("Program_A_graph.png", \'r\')\n                if (time.time()-(os.path.getmtime("Program_A_graph.png")) < 1.75):\n                    break\n            except OSError as identifier:\n                i = i+1\n                print(identifier)\n                time.sleep(1)\n                if i>5:\n                    print("\xce\xa5\xcf\x80\xce\xae\xcf\x81\xce\xbe\xce\xb5 \xcf\x80\xcf\x81\xcf\x8c\xce\xb2\xce\xbb\xce\xb7\xce\xbc\xce\xb1, \xce\xb4\xce\xb5\xce\xbd \xce\xb5\xce\xba\xcf\x84\xcf\x85\xcf\x80\xcf\x8e\xce\xbd\xcf\x89 \xce\xba\xce\xb1\xce\xb9 \xcf\x83\xcf\x85\xce\xbd\xce\xb5\xcf\x87\xce\xaf\xce\xb6\xcf\x89 \xcf\x83\xcf\x84\xce\xbf \xce\xb5\xcf\x80\xcf\x8c\xce\xbc\xce\xb5\xce\xbd\xce\xbf \xcf\x83\xce\xb5\xcf\x84!")\n                    return\n\n\n    serial_number_message = int(time.time())\n\n    # img.show(title="Final Result")\n    img.convert(\'RGB\').save(\'./\xce\xb5\xce\xba\xcf\x84\xcf\x85\xcf\x80\xcf\x8e\xcf\x83\xce\xb5\xce\xb9\xcf\x82/\'+str(serial_number_message)+\'.pdf\', format="PDF", resolution=100.0)\n\n#win32api.ShellExecute (0, "print", \'./\xce\xb5\xce\xba\xcf\x84\xcf\x85\xcf\x80\xcf\x8e\xcf\x83\xce\xb5\xce\xb9\xcf\x82/\'+str(serial_number_message)+\'.pdf\', \'/d:"%s"\' % printer_name, ".",0)\n#win32api.ShellExecute (0, "print", \'./\xce\xb5\xce\xba\xcf\x84\xcf\x85\xcf\x80\xcf\x8e\xcf\x83\xce\xb5\xce\xb9\xcf\x82/\'+str(serial_number_message)+\'.pdf\', \'/d:"%s"\' % printer_name, "./\xce\xb5\xce\xba\xcf\x84\xcf\x85\xcf\x80\xcf\x8e\xcf\x83\xce\xb5\xce\xb9\xcf\x82",0)\n    HORZRES = 10\n    VERTRES = 10\n\n    PHYSICALWIDTH = 110\n    PHYSICALHEIGHT = 111\n\n    PHYSICALOFFSETX = 112\n    PHYSICALOFFSETY = 113\n\n    hDC = win32ui.CreateDC()\n    hDC.CreatePrinterDC(printer_name)\n    printable_area = hDC.GetDeviceCaps(HORZRES), hDC.GetDeviceCaps(VERTRES)\n    printer_size = hDC.GetDeviceCaps(PHYSICALWIDTH), hDC.GetDeviceCaps(PHYSICALHEIGHT)\n    printer_margins = hDC.GetDeviceCaps(PHYSICALOFFSETX), hDC.GetDeviceCaps(PHYSICALOFFSETY)\n\n    bmp = img\n    if bmp.size[0] > bmp.size[1]:\n        bmp = bmp.rotate(90)\n\n    ratios = [1.0 * printable_area[0] / bmp.size[0], 1.0 * printable_area[1] / bmp.size[1]]\n    scale = min(ratios)\n\n    hDC.StartDoc("Result")\n    hDC.StartPage()\n\n    dib = ImageWin.Dib(bmp)\n    scaled_width, scaled_height = [int(scale * i) for i in bmp.size]\n    x1 = int((printer_size[0] - scaled_width) / 2)\n    y1 = int((printer_size[1] - scaled_height) / 2)\n    x2 = x1 + scaled_width\n    y2 = y1 + scaled_height\n    dib.draw(hDC.GetHandleOutput(), (x1, y1, x2, y2))\n\n    hDC.EndPage()\n    hDC.EndDoc()\n    hDC.DeleteDC()\n
Run Code Online (Sandbox Code Playgroud)\n\n

我不知道还能尝试什么。有办法实现这一点吗?

\n

Bar*_*ani 5

bmp = bmp.rotate(90)
Run Code Online (Sandbox Code Playgroud)

这将裁剪图像。用于img.rotate(90, expand=True)正确翻转图像。

您可以使用SetViewportExt/SetWindowExt来代替手动计算位图与打印机分辨率的比率。您还需要考虑打印机的边距。请参阅下面的示例。

文件未找到错误的系统错误是单独的。使用调试器来查找它发生的位置。

import win32ui, win32con
from PIL import Image, ImageWin

def print_test(printer_name):

    try:
        filename = "Program_A_graph.png"
        img = Image.open(filename, 'r')
    except:
        print("error")
        return

    hdc = win32ui.CreateDC()
    hdc.CreatePrinterDC(printer_name)

    horzres = hdc.GetDeviceCaps(win32con.HORZRES)
    vertres = hdc.GetDeviceCaps(win32con.VERTRES)

    landscape = horzres > vertres

    if landscape:
        if img.size[1] > img.size[0]:
            print('Landscape mode, tall image, rotate bitmap.')
            img = img.rotate(90, expand=True)
    else:
        if img.size[1] < img.size[0]:
            print('Portrait mode, wide image, rotate bitmap.')
            img = img.rotate(90, expand=True)

    img_width = img.size[0]
    img_height = img.size[1]

    if landscape:
        #we want image width to match page width
        ratio = vertres / horzres
        max_width = img_width
        max_height = (int)(img_width * ratio)
    else:
        #we want image height to match page height
        ratio = horzres / vertres
        max_height = img_height
        max_width = (int)(max_height * ratio)

    #map image size to page size
    hdc.SetMapMode(win32con.MM_ISOTROPIC)
    hdc.SetViewportExt((horzres, vertres));
    hdc.SetWindowExt((max_width, max_height))

    #offset image so it is centered horizontally
    offset_x = (int)((max_width - img_width)/2)
    offset_y = (int)((max_height - img_height)/2)
    hdc.SetWindowOrg((-offset_x, -offset_y)) 

    hdc.StartDoc('Result')
    hdc.StartPage()

    dib = ImageWin.Dib(img)
    dib.draw(hdc.GetHandleOutput(), (0, 0, img_width, img_height))

    hdc.EndPage()
    hdc.EndDoc()
    hdc.DeleteDC()

    print( 'Debug info:' )
    print( 'Landscape: %d' % landscape )
    print( 'horzres: %d' % horzres )
    print( 'vertres: %d' % vertres )

    print( 'img_width: %d' % img_width )
    print( 'img_height: %d' % img_height )

    print( 'max_width: %d' % max_width )
    print( 'max_height: %d' % max_height )

    print( 'offset_x: %d' % offset_x )
    print( 'offset_y: %d' % offset_y )
Run Code Online (Sandbox Code Playgroud)