python:使用Windows API来使用ttf字体来呈现文本 [英] python: use windows api to render text using a ttf font

查看:1458
本文介绍了python:使用Windows API来使用ttf字体来呈现文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是一个完整的例子,从无到有在内存中的位图,打开一个特定的 .ttf 文件并使用该字体渲染一些文本,使用本机Windows API?我目前正在通过windows API进行浏览,所以这是我和其他人之间的竞争。

完成并完成(需要PyWin32):

  import ctypes 
import struct
import win32con
导入win32gui
导入win32ui

从PIL导入图像


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)

#填充行至4字节
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})

#创建一个兼容的DC,我们可以使用绘制:
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。字体)
$ b $ def def renderText(self,text):
使用windows API将文本呈现给PIL图像。
self.drawDC.SetTextColor(RGB (255,0,0))

#创建兼容的位图:
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())

返回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())

用法:

 >>> f = Win32Font(Arial,15)
>>> im = f.renderText(这只是一个测试)
>>> im.save(c:/hope.png)

结果:



GLORY http://i53.tinypic.com/2qvxf2u.png



精彩!!!

为了呈现特定的 .ttf file我需要挖掘更多。



更新:更新以计算bmp大小:



woot http://i51.tinypic.com/s4rq7s.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:

GLORY http://i53.tinypic.com/2qvxf2u.png

brilliant!!!

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

UPDATE: Updated to calculate the bmp size:

woot http://i51.tinypic.com/s4rq7s.png

这篇关于python:使用Windows API来使用ttf字体来呈现文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆