gpt4 book ai didi

python - 如何完全按照显示的字体呈现字体?

转载 作者:行者123 更新时间:2023-12-04 14:48:06 26 4
gpt4 key购买 nike

我在一个游戏里发现了一个肯定是用微软雅黑字体的脚本(当我把我在游戏文件夹里找到的字体文件替换成我自己的字体文件时,脚本字体也跟着变了):

enter image description here

但是即使改变了大小和位置参数,渲染结果总是有点不同。

from PIL import Image, ImageDraw, ImageFont
import numpy as np

i = 12
text = '我是王中王'

font = ImageFont.truetype('mysh.ttf', i)
PIL_image = Image.new('RGB', (100, 100), color=0xffffff)
draw = ImageDraw.Draw(PIL_image)
draw.text((31, 11), text, font=font, fill=10, anchor='mm')
Image.fromarray(np.array(PIL_image)).save('out.png')

这是我正在使用的一段代码,通过更改 font_size 参数,最接近的结果是:

enter image description here

尝试使用 windows paint,获得与 PIL 相同的字体:

enter image description here

略有不同,您应该可以找到它:

enter image description here

我意识到位置参数可能是小数,但是枕头文本方法似乎将小数点位置参数截断为整数,将位置参数更改为小数没有区别。我该怎么办?

最佳答案

问题既不在 PIL 中,也不在您的代码中,您做对了,但在处理图像中的字体渲染时请记住。

你的问题

  1. 这是一个非常复杂的问题,实现了很多次,改进了很多次,仍然是一个非常庞大的研究课题。
  2. PIL 使用自己的字体渲染引擎,“Microsoft YaHei”意味着您很可能在 Windows 中运行代码,它有自己的渲染引擎,这只是一个假设。
  3. PIL 和 Windows 中的这种实现更改总是会产生一些差异,如果您为这两者提供相同的参数,则无关紧要。

解决方案

  1. Use Win32API in python 在python中使用windows rendering engine来获得几乎相同或至少最接近的结果。

  2. 或者尝试使用游戏库 pygame 进行实验,因为它是为开发而生的游戏,因此它将更精确地处理字体渲染并使用实现可靠性的复杂方法。

使用 Windows API

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

并使用它

f = Win32Font("Your Font Name e.g. Microsoft YaHei", 15) #to use your font file install the font in windows
im = f.renderText("your text") #render your text
im.save("/path/to/image") #save your image if needed

使用 Pygame

pygfont = pygame.font.Font(r"c:\windows\fonts\yourcustomfont.ttf", 15)
surf = pygfont.render("your text to render", False, (0,0,0), (255,255,255)) #False means anti aliasing disabled, you can experiment with enabled flag also
pygame.image.save(surf, r"/path/to/your/image")

要安装 pygame 运行 pip install pygame for python2 或 pip3 install pygame for python3

关于python - 如何完全按照显示的字体呈现字体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69612305/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com