我正在尝试使用Python程序从Excel .xls文件中读取一系列非西方(日文/中文)Unicode字符串,并为每个字符串创建一个图像文件。 xlrd模块为我提供了Excel文件中的Unicode字符串,它们可以正确显示。
对previous question的回答提供了一些在Python中使用Windows API将普通西方文本呈现为图像文件的基本元素。但是,如果我更改为基本调用以从Unicode文本字符串中呈现2个日语字符:
f = Win32Font("MS Gothic", 24)
im = f.renderText(u'\u30bb\u30c3')
im.save("hope.png")
代码失败:UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
使用Windows API正确呈现Unicode字符串的任何帮助都将非常感激。
答案 0 :(得分:0)
您需要使用Win32Api的Unicode版本。通过快速浏览其他问题的链接,您在win32gui.DrawTextW
实施中至少需要win32ui.DrawText
而不是Win32Font
。注意win32 g ui是本机API而不是win32ui
包含的MFC API。我在pywin32
文档的快速浏览中没有看到使用Unicode版本的MFC调用的方法,因此您需要使用{{1}从PyCDC
中获取本机句柄将它与原生API一起使用。
如果您需要更多帮助,请发布完整示例。
答案 1 :(得分:0)
我花了几十个小时寻找一个unicode ... W win32 ...函数,直到Mark Tolonen的答案,我已经立即将其实现为一个工作示例,其代码如下所示。如果一切正常,你的打印机应该输出一个字符串“汉字,にほんご,עברית,عربي我都会刷出。”。
# -*- coding: utf-8 -*-
import win32ui, win32con, win32gui, win32print, traceback
# init, bla bla bla
printername = win32print.GetDefaultPrinter()
hprinter = win32print.OpenPrinter(printername)
# load default settings
devmode = win32print.GetPrinter(hprinter, 8)["pDevMode"]
# this is where it gets INTERESTING:
# after the following two lines, use:
# dc for win32ui calls like LineTo, SelectObject, ...
# hdc for DrawTextW, your *MAGIC* function that supports unicode output
hdc = win32gui.CreateDC("WINSPOOL", printername, devmode)
dc = win32ui.CreateDCFromHandle(hdc)
# 1440 twips = 1 inch
dc.SetMapMode(win32con.MM_TWIPS)
# 20 twips = 1 pt
scale_factor = 20
# start the document, description as unicode
description = u'Test1'
dc.StartDoc(description)
# when working with the printer, enclose any potentially failing calls within a try block,
# because if you do not properly end the print job (see bottom), after a couple of such failures,
# you might need to restart windows as it runs out of handles or something and starts
# behaving in an unpredictable way, some documents fail to print, you cannot open windows, etc.
try :
# Use a font
font = win32ui.CreateFont({
"name": "Arial Unicode MS", # a font name
"height": int(scale_factor * 10), # 10 pt
"weight": 400, # 400 = normal
})
# use dc -- SelectObject is a win32ui call
dc.SelectObject(font)
# this is the miracle where the unicode text gets to be printed; notice hdc,
# not dc, for DrawTextW uses a different handle, i have found this in other posts
win32gui.DrawTextW (hdc, u"\u6C49\u5B57\u3001\u306B\u307B\u3093\u3054\u3001\u05E2\u05D1\u05E8\u05D9\u05EA\u3001\u0639\u0631\u0628\u064A\u6211\u90FD\u4F1A\u5237\u51FA\u3002", -1, (0, -2000, 4000, -4000), win32con.DT_CENTER)
except :
traceback.print_exc()
# must not forget to tell Windows we're done. This line must get called if StartDoc
# was called, if you fail to do so, your sys might start behaving unexpectedly
dc.EndDoc()
答案 2 :(得分:0)
# -*- coding: utf-8 -*-
import win32ui, win32con, win32gui, win32print, traceback
# init, bla bla bla
printername = win32print.GetDefaultPrinter()
hprinter = win32print.OpenPrinter(printername)
# load default settings
devmode = win32print.GetPrinter(hprinter, 8)["pDevMode"]
# this is where it gets INTERESTING:
# after the following two lines, use:
# dc for win32ui calls like LineTo, SelectObject, ...
# hdc for DrawTextW, your *MAGIC* function that supports unicode output
hdc = win32gui.CreateDC("WINSPOOL", printername, devmode)
dc = win32ui.CreateDCFromHandle(hdc)
# 1440 twips = 1 inch
dc.SetMapMode(win32con.MM_TWIPS)
# 20 twips = 1 pt
scale_factor = 20
# start the document, description as unicode
description = u'Test1'
dc.StartDoc(description)
# when working with the printer, enclose any potentially failing calls within a try block,
# because if you do not properly end the print job (see bottom), after a couple of such failures,
# you might need to restart windows as it runs out of handles or something and starts
# behaving in an unpredictable way, some documents fail to print, you cannot open windows, etc.
try :
# Use a font
font = win32ui.CreateFont({
"name": "Arial Unicode MS", # a font name
"height": int(scale_factor * 10), # 10 pt
"weight": 400, # 400 = normal
})
# use dc -- SelectObject is a win32ui call
dc.SelectObject(font)
# this is the miracle where the unicode text gets to be printed; notice hdc,
# not dc, for DrawTextW uses a different handle, i have found this in other posts
win32gui.DrawTextW (hdc, u"\u6C49\u5B57\u3001\u306B\u307B\u3093\u3054\u3001\u05E2\u05D1\u05E8\u05D9\u05EA\u3001\u0639\u0631\u0628\u064A\u6211\u90FD\u4F1A\u5237\u51FA\u3002", -1, (0, -2000, 4000, -4000), win32con.DT_CENTER)
except :
traceback.print_exc()
# must not forget to tell Windows we're done. This line must get called if StartDoc
# was called, if you fail to do so, your sys might start behaving unexpectedly
dc.EndDoc()
如何使用这段代码打印bmp文件?我需要打印二维码 我有 bmp 文件 我收到此错误 - ( win32gui.DrawTextW(hdc, img, -1, (0, -2100, 4000, -4000), win32con.DT_CENTER) 类型错误:“PilImage”类型的对象无法转换为 Unicode。)