在python中将图像转换为字节文字 - python

我正在尝试将图像存储为文本,以便可以为Tk gui的透明图标示例执行以下操作:

import tempfile

# byte literal code for a transparent icon, I think
ICON = (b'\x00\x00\x01\x00\x01\x00\x10\x10\x00\x00\x01\x00\x08\x00h\x05\x00\x00'
        b'\x16\x00\x00\x00(\x00\x00\x00\x10\x00\x00\x00 \x00\x00\x00\x01\x00'
        b'\x08\x00\x00\x00\x00\x00@\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        b'\x00\x01\x00\x00\x00\x01') + b'\x00'*1282 + b'\xff'*64

# makes a temp file for the transparent icon and saves it
_, ICON_PATH = tempfile.mkstemp()
with open(ICON_PATH, 'wb') as icon_file:
    icon_file.write(ICON)

我已经尝试过使用base 64编码,使用utf8解码,转换为字节和字节数组以及其他文章的一些答案:(Python Script to convert Image into Byte array)

import tempfile, base64, io

# byte literal code for a transparent icon, I think
ICON = (b'\x00\x00\x01\x00\x01\x00\x10\x10\x00\x00\x01\x00\x08\x00h\x05\x00\x00'
        b'\x16\x00\x00\x00(\x00\x00\x00\x10\x00\x00\x00 \x00\x00\x00\x01\x00'
        b'\x08\x00\x00\x00\x00\x00@\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        b'\x00\x01\x00\x00\x00\x01') + b'\x00'*1282 + b'\xff'*64

# makes a temp file for the transparent icon and saves it
_, ICON_PATH = tempfile.mkstemp()
with open(ICON_PATH, 'wb') as icon_file:
    icon_file.write(ICON)

a = open(ICON_PATH, 'rb').read()

b = base64.b64encode(a)

print b # output does not match what ICON equals above

# doesn't work; gives error
# UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 1342: invalid start byte
# b = bytes(a).decode('utf-8') 

c = bytearray(a)

print c # prints garbled junk


# gives error AttributeError: __exit__ on Image.open(ICON_PATH) line
with io.BytesIO() as output:
    from PIL import Image
    with Image.open(ICON_PATH) as img:
        img.convert('RGB').save(output, 'BMP')                
    data = output.getvalue()[14:]

print data

它也不适用于b.decode('utf-8')或b.encode('utf-8')

python大神给出的解决方案

我想你在找

print(repr(a))

对于代码中定义的a,它会打印b'\x00\x00\x01\x00\x01\x00\x10\x10\x00\x00\x01\x00\x08\x00h\x05\x00\x00\x16\x00\x00\x00(\x00\x00\x00\x10\x00\x00\x00 \x00\x00\x00\x01\x00\x08,依此类推,类似于原始的ICON定义,但是它很大,因为末尾的所有\x00\xff都被写出。

在您的代码中,您包括了一些临时压缩(即+ b'\x00'*1282 + b'\xff'*64)。要自动获取压缩,因此源文件中的ICON定义不必太大,请利用现有的压缩库,例如zlib:

import zlib
print(repr(zlib.compress(a)))

在我的机器上,这会打印'x\x9cc``\x04B\x01\x01\x06 \xc9\xc1\x90\xc1\xca\xc0 \xc6\xc0\xc0\xa0\x01\xc4@!\x06\x05\x06\x888\x088\xb02 \x00#\x14\x8f\x82Q0\nF\xc1\x08\x05\xff)\x04\x00U\xf1A\x17',它很小。要解压缩,请使用zlib.decompress:

import zlib

ICON = zlib.decompress(b'x\x9cc``\x04B\x01\x01\x06 \xc9\xc1\x90\xc1\xca\xc0 '
    b'\xc6\xc0\xc0\xa0\x01\xc4@!\x06\x05\x06\x888\x088\xb02 \x00#\x14\x8f\x82'
    b'Q0\nF\xc1\x08\x05\xff)\x04\x00U\xf1A\x17')

ICON现在具有与原始示例相同的值。

如果现在您想要一个在源文件中更紧凑的表示形式,那么该应用base 64编码了,该编码摆脱了python(\x..-格式)中的冗长二进制编码。

编码:

import base64, zlib

print(repr(base64.b64encode(zlib.compress(a))))

这给了我'eJxjYGAEQgEBBiDJwZDBysAgxsDAoAHEQCEGBQaIOAg4sDIgACMUj4JRMApGwQgF/ykEAFXxQRc='

解码:

import base64, zlib

ICON = zlib.decompress(base64.b64decode('eJxjYGAEQgEBBiDJwZDBy'
    'sAgxsDAoAHEQCEGBQaIOAg4sDIgACMUj4JRMApGwQgF/ykEAFXxQRc='))

同样,ICON具有与最初指定的值相同的值。

所示的最终策略适用于ico文件。我看到您还提到了png文件。这些已经应用了压缩,因此您可能应该更喜欢只使用base 64编码:

import base64

print(base64.b64encode(png_icon))

PNG_ICON = base64.b64decode( ** insert literal here ** )

事实证明,这些编码也可以通过str.encode和str.decode API使用。这使您无需编写import即可退出。为了完整起见,它们是:

编码方式:

print(repr(a.encode('zlib').encode('base64')))

解码:

ICON = ('eJxjYGAEQgEBBiDJwZDBysAgxsDAoAHEQCEGBQaIOAg4sDIgACMUj4J'
    'RMApGwQgF/ykEAFXxQRc=').decode('base64').decode('zlib')