簡體   English   中英

Python:使用 Windows API 創建日文/中文文本的 Unicode 渲染

[英]Python: use Windows API to create Unicode rendering of Japanese/Chinese text

我正在嘗試使用 Python 程序從 Excel .xls 文件中讀取一系列非西方(日語/中文)Unicode 字符串,並為每個字符串創建一個圖像文件。 xlrd 模塊為我提供 Excel 文件中的 Unicode 字符串,並在其中正確顯示。

對上一個問題的回答提供了一些基本元素,以使用 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 字符串的任何幫助將不勝感激。

您需要使用 Unicode 版本的 Win32Api。 在從其他的問題,你的鏈接的一瞥至少需要win32gui.DrawTextW而不是win32ui.DrawTextWin32Font實施。 注意 win32 g ui 是本機 API,而不是win32ui包裝的 MFC API。 在我對pywin32文檔的快速瀏覽中,我沒有看到使用 MFC 調用的 Unicode 版本的方法,因此您需要使用GetSafeHdcPyCDC獲取本機句柄,以便將其與本機 API 一起使用。

如果您需要更多幫助,請發布一個完整的示例。

我花了幾十個小時尋找 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()
# -*- 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) TypeError: Objects of type 'PilImage'無法轉換為 Unicode。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM