【问题标题】:Decode Base64 after it has been saved as a string object?将 Base64 保存为字符串对象后解码它?
【发布时间】:2023-12-29 02:42:01
【问题描述】:

我对 Python 还很陌生,正在尝试编译一个文本 (.txt) 文档,该文档充当保存文件,以后可以加载。

我希望它是一个独立的文档,其中包含用户正在使用的所有属性(包括一些我希望作为编码的 base64 二进制字符串保存在文件中的图像)。

我已经编写了程序,它会将所有内容正确地保存到文本文件中(尽管我确实必须通过 str() 传递编码值),但我以后无法访问图像进行解码。这是我创建文本信息的示例:

if os.path.isfile("example.png"): #if the user has created this type of image..  
    with open("example.png", "rb") as image_file:
        image_data_base64_encoded_string = base64.b64encode(image_file.read())
        f = open("example_save.txt",'a+')
        f.write("str(image_data_base64_encoded_string)+"\n")
        f.close() #save its information to the text doc

这是我重新访问此信息的众多尝试之一。

master.filename =  filedialog.askopenfilename(initialdir = "/",title = "Select file",filetypes = ((".txt files","*.txt"),("all files","*.*")))
with open(master.filename) as f:
    image_import = ((f.readlines()[3]))#pulling the specific line the data string is in

image_imported = tk.PhotoImage(data=image_import)

这只是我最近的一次尝试——并且仍然返回错误。我尝试在传递给 tkinter PhotoImage 函数之前对编码信息进行解码,但我认为 Python 可能会将编码信息视为字符串(因为我在保存信息时将其设为字符串)但我不知道如何将其更改回来更改信息。

任何帮助将不胜感激。

【问题讨论】:

  • 您遇到的错误是什么?
  • 您在以f.write( 开头的行中有一个放错位置的双引号,在原始代码示例中也有吗?
  • 考虑为此使用pickle 模块,而不是滚动您自己的持久性机制。
  • 您的语法错误导致此代码无法正常工作 - 在您第一次调用 write 时存在一组不平衡的引号。您能否修复它,以便我们确切地知道您在做什么?
  • 你是对的,那是我删除一些不必要的信息的残余。代码的写入部分在原始公式中起作用。

标签: python string tkinter base64 photoimage


【解决方案1】:

我建议使用 Pillow 模块来处理图像,但如果您坚持当前的方式,请尝试以下代码:

from tkinter import *
import base64
import os

if os.path.isfile("example.png"): #if the user has created this type of image..  
    with open("example.png", "rb") as image_file:
        image_data_base64_encoded_string = base64.b64encode(image_file.read())
        f = open("example_save.txt",'a+')
       f.write(image_data_base64_encoded_string.decode("utf-8")+"\n")
       f.close() 

filename =  filedialog.askopenfilename(initialdir = "/",title = "Select file",filetypes = ((".txt files","*.txt"),("all files","*.*")))
with open(filename) as f:
    image_import = f.readlines()[3].strip()
image_imported = PhotoImage(data=image_import)

您看到您的字符串需要是 utf-8 并且尾随换行符也阻止 PhotoImage() 将您的图像数据解释为图像。

【讨论】:

  • 无需拉入 PIL 或 Pillow。这只会带来额外的开销,并不能解决这个问题。
  • 我的错......在这个例子中不需要它。
  • 我在代码的其他地方确实有 PIL 模块,如果它可以更好地工作,我愿意在这里使用它!
  • 我已经实现了上述更改,它们运行良好。但是,当我尝试将导入的图像写入文件 (.png) 时,我最终会得到一个乱码。我可能会发布一个单独的问题,但有什么想法吗?
  • 请使用 Pillow 将图像写入文件。您可以简单地解码base64并使用BytesIO将数据传递给枕头然后保存图像frombytes()
【解决方案2】:

当你这样写出值时:

str(image_data_base64_encoded_string)

就是这样写的:

b'...blah...'

查看你正在编写的文件,你会发现该行被b' '包围。

您想将二进制文件解码为适合您文件的编码,例如:

f.write(image_data_base64_encoded_string.decode('utf-8') + "\n")

【讨论】:

  • 我会在原始写语句中包含这个吗?当我把它读回来时,我可以把它以这种形式交给 PhotoImage 吗?
  • 我相信是这样,当您在现有代码中说 str(image_data_base64_encoded_string) 时,它只是向您展示了一个字符串表示以供人类阅读,而 b'...' 在那里向您表明它是二进制的数据。当您写入文本文件时,您希望将二进制文件转换为实际字符串,而b'...' 不打算成为字符串二进制转换的一部分。