[英]convert image to byte literal in 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腳本將Image轉換為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')
我想你在找
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
最后寫出\\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..
-format)中的冗長二進制編碼。
編碼:
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')
我認為您只是沒有正確打印出數據-似乎沒有必要搞亂base64
這樣做。
這是證明:
from itertools import izip
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
# make a temp file from ICON data for testing
_, ICON_PATH = tempfile.mkstemp()
with open(ICON_PATH, 'wb') as icon_file:
icon_file.write(ICON)
# Convert raw data in the file into a valid Python string literal.
# helper function
def grouper(n, seq):
"s -> (s0,s1,...sn-1), (sn,sn+1,...s2n-1), (s2n,s2n+1,...s3n-1), ..."
for i in xrange(0, len(seq), n):
yield seq[i:i+n]
# read data file in binary mode
a = open(ICON_PATH, 'rb').read()
# create Python code to define string literal
code = '\n'.join(['ICON2 = ('] +
[' '+repr(group) for group in grouper(16, a)] +
[')'])
print 'len(ICON): {}'.format(len(ICON))
print 'len(a): {}'.format(len(a))
print code
exec(code)
print
print 'len(ICON2): {}'.format(len(ICON2))
print 'ICON2 == ICON: {}'.format(ICON2 == ICON)
輸出:
len(ICON): 1406
len(a): 1406
ICON2 = (
'\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\x00\x00\x00\x00\x00@\x05\x00\x00\x00\x00'
'\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00'
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
...
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff'
'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
)
len(ICON2): 1406
ICON2 == ICON: True
好吧,我確實知道您可以通過以下方式做到這一點:
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)
with open(ICON_PATH, 'rb') as imgFile:
a = imgFile.read()
b = base64.b64encode(a)
print b # output does not match what ICON equals above
with open('test.png','wb') as writeFile:
writeFile.write(b.decode('base64'))
但我仍然想知道如何獲得與頂部的'ICON =(...')相同的格式
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.