python使用ttf文件_python:使用Windows API来使用ttf字体来呈现文本

本文提供了一个使用Windows API从特定.ttf文件中加载字体并渲染文本到位图内存的完整示例。通过Python脚本实现,涵盖了创建兼容设备环境、选择字体、绘制文本及转换为PIL图像等过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1586010002-jmsa.png

What would be a full example, going from nothing to ending up with a bitmap in memory, of opening a particular .ttf file and rendering some text using that font, using the native Windows API? I'm currently slogging through the windows API, so it's a race between me and the rest of stackoverflow.

解决方案

Done and done for rendering a font (requires PyWin32):

import ctypes

import struct

import win32con

import win32gui

import win32ui

from PIL import Image

def RGB(r, g, b):

return r | (g << 8) | (b << 16)

def native_bmp_to_pil(hdc, bitmap_handle, width, height):

bmpheader = struct.pack("LHHHH", struct.calcsize("LHHHH"),

width, height, 1, 24) #w,h, planes=1, bitcount)

c_bmpheader = ctypes.c_buffer(bmpheader)

#3 bytes per pixel, pad lines to 4 bytes

c_bits = ctypes.c_buffer(" " * (height * ((width*3 + 3) & -4)))

res = ctypes.windll.gdi32.GetDIBits(

hdc, bitmap_handle, 0, height,

c_bits, c_bmpheader,

win32con.DIB_RGB_COLORS)

if not res:

raise IOError("native_bmp_to_pil failed: GetDIBits")

im = Image.frombuffer(

"RGB", (width, height), c_bits,

"raw", "BGR", (width*3 + 3) & -4, -1)

return im

class Win32Font:

def __init__(self, name, height, weight=win32con.FW_NORMAL,

italic=False, underline=False):

self.font = win32ui.CreateFont({

'name': name, 'height': height,

'weight': weight, 'italic': italic, 'underline': underline})

#create a compatible DC we can use to draw:

self.desktopHwnd = win32gui.GetDesktopWindow()

self.desktopDC = win32gui.GetWindowDC(self.desktopHwnd)

self.mfcDC = win32ui.CreateDCFromHandle(self.desktopDC)

self.drawDC = self.mfcDC.CreateCompatibleDC()

#initialize it

self.drawDC.SelectObject(self.font)

def renderText(self, text):

"""render text to a PIL image using the windows API."""

self.drawDC.SetTextColor(RGB(255,0,0))

#create the compatible bitmap:

w,h = self.drawDC.GetTextExtent(text)

saveBitMap = win32ui.CreateBitmap()

saveBitMap.CreateCompatibleBitmap(self.mfcDC, w, h)

self.drawDC.SelectObject(saveBitMap)

#draw it

self.drawDC.DrawText(text, (0, 0, w, h), win32con.DT_LEFT)

#convert to PIL image

im = native_bmp_to_pil(self.drawDC.GetSafeHdc(), saveBitMap.GetHandle(), w, h)

#clean-up

win32gui.DeleteObject(saveBitMap.GetHandle())

return im

def __del__(self):

self.mfcDC.DeleteDC()

self.drawDC.DeleteDC()

win32gui.ReleaseDC(self.desktopHwnd, self.desktopDC)

win32gui.DeleteObject(self.font.GetSafeHandle())

def __del__(self):

win32gui.DeleteObject(self.font.GetSafeHandle())

usage:

>>> f = Win32Font("Arial", 15)

>>> im = f.renderText("this is just a test")

>>> im.save("c:/hope.png")

result:

brilliant!!!

To render a particular .ttf file I'll need to dig around more.

UPDATE: Updated to calculate the bmp size:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值