【问题标题】:Encoding an image file with base64使用 base64 编码图像文件
【发布时间】:2011-04-12 13:03:42
【问题描述】:

我想使用 base64 模块将图像编码为字符串。我遇到了一个问题。如何指定要编码的图像?我尝试使用图像的目录,但这只会导致目录被编码。我希望对实际的图像文件进行编码。

编辑

我试过这个 sn-p:

with open("C:\Python26\seriph1.BMP", "rb") as f:
    data12 = f.read()
    UU = data12.encode("base64")
    UUU = base64.b64decode(UU)

    print UUU

    self.image = ImageTk.PhotoImage(Image.open(UUU))

但我收到以下错误:

Traceback (most recent call last):
  File "<string>", line 245, in run_nodebug
  File "C:\Python26\GUI1.2.9.py", line 473, in <module>
    app = simpleapp_tk(None)
  File "C:\Python26\GUI1.2.9.py", line 14, in __init__
    self.initialize()
  File "C:\Python26\GUI1.2.9.py", line 431, in initialize
    self.image = ImageTk.PhotoImage(Image.open(UUU))
  File "C:\Python26\lib\site-packages\PIL\Image.py", line 1952, in open
    fp = __builtin__.open(fp, "rb")
TypeError: file() argument 1 must be encoded string without NULL bytes, not str

我做错了什么?

【问题讨论】:

    标签: python base64


    【解决方案1】:

    我不确定我是否理解您的问题。我假设你正在做一些事情:

    import base64
    
    with open("yourfile.ext", "rb") as image_file:
        encoded_string = base64.b64encode(image_file.read())
    

    当然,您必须先打开文件并读取其内容 - 您不能简单地将路径传递给编码函数。

    编辑: 好的,这是您编辑原始问题后的更新。

    首先,请记住在 Windows 上使用路径分隔符时使用原始字符串(字符串前缀为 'r'),以防止意外碰到转义字符。其次,PIL 的 Image.open 要么接受文件名,要么接受文件名(即对象必须提供 read、seek 和 tell 方法)。

    话虽如此,您可以使用 cStringIO 从内存缓冲区创建这样的对象:

    import cStringIO
    import PIL.Image
    
    # assume data contains your decoded image
    file_like = cStringIO.StringIO(data)
    
    img = PIL.Image.open(file_like)
    img.show()
    

    【讨论】:

    • 谢谢,当我打印解码图像时,又遇到了一个问题,我得到了字符串“ÿØÿà”。但是,当我单独运行它来代替数据时,我得到一个错误。用于比较的编码字符串要长得多。所以我认为这可能会存储图像数据。解码的字符串只是引用编码的字符串还是什么?数据存储似乎太短了。
    • 打印输出不一定等于实际内容 - 这取决于您打印它的方式和位置。
    • 就我而言,我需要解码:base64.b64encode(fh.read()).decode() 以获取要在 html 文件中使用的字符串。
    • base64.b64encode(fh.read()).decode() 很微妙,但我也需要这个@qed,谢谢。不同之处在于一个返回字节和其他字符串......我的 SOAP 服务器不会在不解码的情况下吞下它!
    【解决方案2】:

    第一个答案将打印一个带有前缀 b' 的字符串。 这意味着您的字符串将像这样 b'your_string' 要解决此问题,请添加以下代码行。

    encoded_string= base64.b64encode(img_file.read())
    print(encoded_string.decode('utf-8'))
    

    我在将 Image 转换为 Base64 字符串时遇到过这种情况。你也可以看看我是如何从那里删除它的。链接在这里Image to base64 string and fix 'b from prefix

    【讨论】:

    • 这看起来是个不错的答案,但如果是为了宣传您的网站,请不要发帖。不过,欢迎您将链接添加到您的个人资料中。
    • (顺便说一句,这里不能依赖答案顺序,所以值得避免像“第一个答案”这样的cmets。最先出现的可能会随着时间的推移而改变。:-)
    • 在此答案的原始版本中,您似乎链接到您自己的网站或您所属的网站。如果您确实链接到此类网站,您必须披露它是您的网站。如果您不披露从属关系,则将其视为垃圾邮件。请参阅:What signifies "Good" self promotion?the help center on self-promotion。披露必须是明确的,但不需要是正式的。如果是您自己的个人内容,则可以是“在我的网站上……”、“在我的博客上……”等。
    • 感谢@Makyen 的建议,我将透露这是我的网站。现在编辑答案以披露它是我的网站是否合法?或者我不应该编辑它。
    【解决方案3】:
    import base64
    from PIL import Image
    from io import BytesIO
    
    with open("image.jpg", "rb") as image_file:
        data = base64.b64encode(image_file.read())
    
    im = Image.open(BytesIO(base64.b64decode(data)))
    im.save('image1.png', 'PNG')
    
    

    【讨论】:

    • 这个答案真的应该排在首位......最好的一个 - 谢谢!
    【解决方案4】:

    借用Ivo van der Wijkgnibbler之前的开发,这是一个动态的解决方案

    import cStringIO
    import PIL.Image
    
    image_data = None
    
    def imagetopy(image, output_file):
        with open(image, 'rb') as fin:
            image_data = fin.read()
    
        with open(output_file, 'w') as fout:
            fout.write('image_data = '+ repr(image_data))
    
    def pytoimage(pyfile):
        pymodule = __import__(pyfile)
        img = PIL.Image.open(cStringIO.StringIO(pymodule.image_data))
        img.show()
    
    if __name__ == '__main__':
        imagetopy('spot.png', 'wishes.py')
        pytoimage('wishes')
    

    然后您可以决定使用Cython 编译输出图像文件以使其更酷。使用这种方法,您可以将所有图形捆绑到一个模块中。

    【讨论】:

      【解决方案5】:

      正如我在您之前的问题中所说,不需要对字符串进行 base64 编码,它只会使程序变慢。只需使用代表

      >>> with open("images/image.gif", "rb") as fin:
      ...  image_data=fin.read()
      ...
      >>> with open("image.py","wb") as fout:
      ...  fout.write("image_data="+repr(image_data))
      ...
      

      现在图像作为一个名为image_data 的变量存储在一个名为image.py 的文件中 启动一个新的解释器并导入 image_data

      >>> from image import image_data
      >>>
      

      【讨论】:

      • 我真的不明白 repr() 在这里有什么用处。
      • @Ivo,Anteater 希望能够将图像存储在 python 文件中。我要指出的是,使用 base64 会适得其反,因为每次加载模块时都需要对数据进行解码。使用 repr 代替意味着文字字符串存储在 .pyc 文件中,可以立即使用,无需进一步处理
      • @JohnLaRooy 非常感谢。我在`fout.write("image_data="+repr(image_data))` 行得到了TypeError: a bytes-like object is required, not 'str'。我该如何解决?
      【解决方案6】:

      对我有用

      import base64
      import requests
      
      # Getting image in bytes
      response = requests.get("image_url") 
      
      # image encoding
      encoded_image = base64.b64encode(response.content)
      
      # image decoding and without it's won't work due to some '\xff' error
      decoded_image= base64.b64decode(encoded_image)
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-01
        • 2014-01-19
        • 1970-01-01
        • 2011-01-31
        • 1970-01-01
        • 2012-12-26
        • 1970-01-01
        相关资源
        最近更新 更多