从临时文件加载的字体文件似乎不正确 [英] Font file loaded from temp file seems incorrect

查看:70
本文介绍了从临时文件加载的字体文件似乎不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 用于 fnt.keys() 中的键:str1 = base64.b64decode(fnt[key])strA = XOR(str1, 编码器)temp = tempfile.TemporaryFile()temp.seek(0)临时写(strA)temp.seek(0)如果键==calibri.ttf":字体 = 温度如果键==calibrib.ttf":字体 = 温度临时关闭()返回(字体,字体)

在上面的代码中,我检索了在字典中保存为字符串的字体.当我使用此代码时,它返回一个错误 - RuntimeError: Can't seek in stream.使用下面的代码,它可以完美运行.有人请解释如何使用临时文件方法来获取字体而不是写入文件.这可能吗?

 用于 fnt.keys() 中的键:str1 = base64.b64decode(fnt[key])strA = XOR(str1, 编码器)使用 open(home + "\\" + key, "wb") 作为 to_disk:to_disk.write(strA)FONT = "calibri.ttf"FONTB = "calibrib.ttf"返回(字体,字体)

我正在添加下面的完整代码.看看这是否有助于给我一个可行的答案.

导入字符串导入 base64导入操作系统从 fnt 导入 fnt导入字符串导入临时文件从 itertools 导入循环,izipdef异或(消息,密钥):cryptedMessage = ''.join(chr(ord(c)^ord(k)) for c,k in izip(message, cycle(key)))返回加密消息#----------------------------------------------------------------------定义主():"""从fnt.py中提取并返回字体文件"""编码器 ="PHdzDER+@k7pcm!LX8gufh=y9A^UaMsn-oW6"家 = os.getcwd()对于 fnt.keys() 中的键:str1 = base64.b64decode(fnt[key])strA = XOR(str1, 编码器)#temp = tempfile.TemporaryFile()#temp.seek(0)#temp.write(strA)#temp.seek(0)#if key == "calibri.ttf":#FONT = 温度#if key == "calibrib.ttf":#FONTB = 温度使用 open(home + "\\" + key, "wb") 作为 to_disk:to_disk.write(strA)FONT = "calibri.ttf"FONTB = "calibrib.ttf"返回(字体,字体)如果 __name__=='__main__':主要的()

解决方案

当 temp 关闭时,它会被销毁,因此您将无法从中读取以提取字体数据.

您在代码的哪一行收到RuntimeError: Can't seek in stream 错误消息?正如 Michael Petch 所说,我们需要了解您的操作系统.tempfile.TemporaryFile() 在 Linux 上肯定是可查找的.

顺便说一句,在

if key == "calibrib.ttf":字体 = 温度临时关闭()

temp.close() 位于 if 块内.我想这可能只是一个副本&粘贴错误.但正如我上面所说的,在您阅读这些文件之前,您不要想要关闭它们.

据推测,您的原始字体读取函数使用文件名从磁盘打开字体文件,然后使用 open() 中的文件句柄访问字体数据.因此,正如 Michael Petch 所说,您需要将其更改为接受来自已打开文件的句柄.

编辑

当您说没有其他字体读取功能"时,我早些时候感到困惑,因为我无法弄清楚您实际上试图用解密的字体数据做什么.

我想我也被你调用字体提取函数 main() 弄糊涂了,因为 main() 通常用作程序的入口点,所以程序通常不会t 在不同的模块中运行一堆不同的 main() 函数.

无论如何...

我从来没有用过 pygame,但可以快速浏览一下 the docs 你可以给 pygame.font.Font() 一个字体名称字符串或一个打开的字体文件句柄作为第一个参数,例如

myfont = pygame.font.Font(font_filehandle, size)

大概你的 fnt 模块有一个包含两串 base64 编码、XOR 加密的字体数据字符串,以字体名称calibrib.ttf"为键.

所以这 应该 工作,假设我没有误解那个 pygame 文档.:)

警告:未经测试的代码

def xor_str(message, key):return ''.join([chr(ord(c)^ord(k)) for c,k in izip(message, cycle(key))])def decode_fonts(fnt):编码器 = "PHdzDER+@k7pcm!LX8gufh=y9A^UaMsn-oW6"font_fh = {}对于 fnt.keys() 中的键:xorfont = base64.b64decode(fnt[key])temp = tempfile.TemporaryFile()temp.write(xor_str(xorfont, 编码器))temp.seek(0)font_fh[key] = temp返回 font_fh#………………#在你的 pygame 函数中:font_fh = decode_fonts(fnt)font_obj = {}对于 font_fh.keys() 中的键:font_obj[key] = pygame.font.Font(font_fh[key], point_size)#现在你可以了surface = font_obj["calibri.ttf"].render(text, antialias, color, background=None)

for key in fnt.keys():

    str1 = base64.b64decode(fnt[key])
    strA = XOR(str1, coder)

    temp = tempfile.TemporaryFile()
    temp.seek(0)
    temp.write(strA)
    temp.seek(0)

    if key == "calibri.ttf":
        FONT = temp
    if key == "calibrib.ttf":
        FONTB = temp
        temp.close()
return (FONT, FONTB)

In the above code I have retrieved fonts saved as a string in a dictionary. When I use this code it returns an error - RuntimeError: Can't seek in stream. With the code below it works perfectly. Someone please explain how to use the temp file method to get the fonts rather than write to file. Is that possible?

for key in fnt.keys():

    str1 = base64.b64decode(fnt[key])
    strA = XOR(str1, coder)

    with open(home + "\\" + key, "wb") as to_disk:
        to_disk.write(strA)
        FONT = "calibri.ttf"
        FONTB = "calibrib.ttf"

return (FONT, FONTB)

I am adding the full code below. See if this helps in giving me a viable answer.

import string
import base64
import os
from fnt import fnt
import string
import tempfile
from itertools import cycle, izip

def XOR(message, key):
    cryptedMessage = ''.join(chr(ord(c)^ord(k)) for c,k in izip(message, cycle(key)))

    return cryptedMessage

#----------------------------------------------------------------------
def main():
    """extracts and returns the font files from fnt.py"""
    coder ="PHdzDER+@k7pcm!LX8gufh=y9A^UaMsn-oW6"
    home = os.getcwd()
    for key in fnt.keys():

        str1 = base64.b64decode(fnt[key])
        strA = XOR(str1, coder)

        #temp = tempfile.TemporaryFile()
        #temp.seek(0)
        #temp.write(strA)
        #temp.seek(0)


        #if key == "calibri.ttf":
            #FONT = temp

        #if key == "calibrib.ttf":
            #FONTB = temp


        with open(home + "\\" + key, "wb") as to_disk:
            to_disk.write(strA)
            FONT = "calibri.ttf"
            FONTB = "calibrib.ttf"

    return (FONT, FONTB)

if __name__=='__main__':
    main()

解决方案

When temp is closed it is destroyed, so you won't be able to read from it to extract the font data.

On what line of your code do you get the RuntimeError: Can't seek in stream error message? As Michael Petch said, we need to know your OS. tempfile.TemporaryFile() is certainly seekable on Linux.

BTW, in

if key == "calibrib.ttf":
    FONTB = temp
    temp.close()

The temp.close() is inside the if block. I guess that might just be a copy & paste error. But as I said above, you don't want to close these files until you've read from them.

Presumably, your original font reading function opens the font files from disk with the filenames and then accesses the font data using the file handle from open(). So as Michael Petch said, you need to change that to accept handles from files that are already open.

EDIT

I got confused earlier when you said that "There is NO other font reading function", since I couldn't figure out what you were actually trying to do with the decrypted font data.

And I guess I also got confused by you calling your font extraction function main(), since main() is conventionally used as the entry-point into a program, so a program normally doesn't run a bunch of different main() functions in different modules.

Anyway...

I've never used pygame, but from a quick look at the docs you can give pygame.font.Font() either a font name string or an open font filehandle as the first arg, eg

myfont = pygame.font.Font(font_filehandle, size)

Presumably your fnt module has a dict containing two strings of base64 encoded, XOR-encrypted font data, keyed by the font names, "calibrib.ttf".

So this should work, assuming I'm not misunderstanding that pygame doc. :)

Warning: Untested code

def xor_str(message, key):
    return ''.join([chr(ord(c)^ord(k)) for c,k in izip(message, cycle(key))])

def decode_fonts(fnt):
    coder = "PHdzDER+@k7pcm!LX8gufh=y9A^UaMsn-oW6"

    font_fh = {}
    for key in fnt.keys():
        xorfont = base64.b64decode(fnt[key])

        temp = tempfile.TemporaryFile()
        temp.write(xor_str(xorfont, coder))
        temp.seek(0)

        font_fh[key] = temp
    return font_fh

#...............

    #In your pygame function:
    font_fh = decode_fonts(fnt)

    font_obj = {}
    for key in font_fh.keys():
        font_obj[key] = pygame.font.Font(font_fh[key], point_size)

    #Now you can do
    surface = font_obj["calibri.ttf"].render(text, antialias, color, background=None)

这篇关于从临时文件加载的字体文件似乎不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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