我想打印我使用指定打印机在脚本上创建的pdf文件(或图像),但是该文件是横向的。我尝试过Tim Golden's python print,但是打印错误,并且大部分图像都没有打印,或者我收到一条错误消息,指出找不到指定的文件。这是错误:“ pywintypes.error:(2,'ShellExecute','系统找不到指定的文件。')” 并且命令是这样的: win32api.ShellExecute(0,“打印”,文件名,'/ d:“%s”'%printer_name,“。”,0) 。当然 filename 和 printer 是字符串,并且打印机名称取自win32print.EnumPrinters(2,None,1)
这是我的打印功能:
def programA_printer():
global name
global printer_name
global event2
# time.sleep(3)
i=0
while True:
if not event2.is_set():
try:
img = Image.open("Program_A_graph.png", 'r')
if (time.time()-(os.path.getmtime("Program_A_graph.png")) < 1.75):
break
except OSError as identifier:
i = i+1
print(identifier)
time.sleep(1)
if i>5:
print("Υπήρξε πρόβλημα, δεν εκτυπώνω και συνεχίζω στο επόμενο σετ!")
return
serial_number_message = int(time.time())
# img.show(title="Final Result")
img.convert('RGB').save('./εκτυπώσεις/'+str(serial_number_message)+'.pdf', format="PDF", resolution=100.0)
#win32api.ShellExecute (0, "print", './εκτυπώσεις/'+str(serial_number_message)+'.pdf', '/d:"%s"' % printer_name, ".",0)
#win32api.ShellExecute (0, "print", './εκτυπώσεις/'+str(serial_number_message)+'.pdf', '/d:"%s"' % printer_name, "./εκτυπώσεις",0)
HORZRES = 10
VERTRES = 10
PHYSICALWIDTH = 110
PHYSICALHEIGHT = 111
PHYSICALOFFSETX = 112
PHYSICALOFFSETY = 113
hDC = win32ui.CreateDC()
hDC.CreatePrinterDC(printer_name)
printable_area = hDC.GetDeviceCaps(HORZRES), hDC.GetDeviceCaps(VERTRES)
printer_size = hDC.GetDeviceCaps(PHYSICALWIDTH), hDC.GetDeviceCaps(PHYSICALHEIGHT)
printer_margins = hDC.GetDeviceCaps(PHYSICALOFFSETX), hDC.GetDeviceCaps(PHYSICALOFFSETY)
bmp = img
if bmp.size[0] > bmp.size[1]:
bmp = bmp.rotate(90)
ratios = [1.0 * printable_area[0] / bmp.size[0], 1.0 * printable_area[1] / bmp.size[1]]
scale = min(ratios)
hDC.StartDoc("Result")
hDC.StartPage()
dib = ImageWin.Dib(bmp)
scaled_width, scaled_height = [int(scale * i) for i in bmp.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()
我不知道还能尝试什么。有没有办法做到这一点?
答案 0 :(得分:2)
bmp = bmp.rotate(90)
这将裁切图像。使用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 )
答案 1 :(得分:0)
@Barmak Shemirani对于下面的大多数代码都应给予充分的评价。我只是添加了一个部分,允许您选择页面大小和/或强制方向。您现在也可以轻松地在win32con中使用devmode来按需推送映像。
def print_test(filename, page_size="11x17", page_orientation="landscape", printer_name = win32print.GetDefaultPrinter()):
try:
img = Image.open(filename, 'r')
except:
print("error")
return
# open the printer.
hprinter = win32print.OpenPrinter(printer_name)
# retrieve default settings. this code does not work on
devmode = win32print.GetPrinter(hprinter, 2)["pDevMode"]
# change paper size and orientation
# all numbers can be found here -
# https://github.com/SublimeText/Pywin32/blob/master/lib/x64/win32/lib/win32con.py
if page_size == "letter":
devmode.PaperSize = 1 # 11x17 = 17, letter = 1
elif page_size == "11x17":
devmode.PaperSize = 17 # 11x17 = 17, letter = 1
# 1 = portrait, 2 = landscape
if page_orientation == "portait":
devmode.Orientation = 2
elif page_orientation == "landscape":
devmode.Orientation = 2
# create dc using new settings
# first get the integer hDC value - note that we need the name
hdc = win32gui.CreateDC("WINSPOOL", printer_name, devmode)
# next create a PyCDC from the hDC.
hdc = win32ui.CreateDCFromHandle(hdc)
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()