簡體   English   中英

在python中將圖像轉換為字節文字

[英]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.encodestr.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM