首页 > 解决方案 > python3将二进制数据转换为字符串并返回

问题描述

我正在使用 python3 以二进制模式打开图像,然后在特定标记 (\xff\xda) 处拆分该数据

该标记之后的所有内容都存储在一个变量中,我想用 e 替换所有 a

但是在将二进制数据转换为字符串时遇到了麻烦:

UnicodeDecodeError:“ascii”编解码器无法解码位置 13 中的字节 0xe6:序数不在范围内(128)

with open(filein, "rb") as rd:
  with open(fileout,'wb') as wr:
    img = rd.read()
    if img.find(b'\xff\xda'): ## ff da start of scan
        splitimg = img.split(b'\xff\xda', 1)
        wr.write(splitimg[0])
        scanimg = splitimg[1]

        scanglitch = ""
        scanimg = scanimg.encode()

        for letter in scanimg :
            if letter not in 'a': 
                scanglitch += letter
            else :
                scanglitch += 'e'

    print(scanimg)

    wr.write(b'\xff\xda')
    content = scanglitch.decode()
    wr.write(content)

encode() 和 decode() 不是将二进制数据转换为字符串并返回的正确方法吗?谢谢

标签: pythonpython-3.xjpeg

解决方案


在处理二进制数据时,您会希望尽可能保持二进制模式,特别是因为不能保证您选择的字符串编码无论如何都可以代表所有值。

请记住bytes,对象基本上是 8 位无符号整数的列表,即使它们具有方便的类似字符串的b'xyz'语法。

filein = "download.jpeg"
fileout = "glitch.jpg"

with open(filein, "rb") as rd:
    img = rd.read()
    # We can happily crash here if there's no FFDA; 
    # that means we're not able to process the file anyway
    prelude, marker, scanimg = img.partition(b"\xff\xda")
    scanglitch = []

    for letter in scanimg:  # scanimg is a list of integers, so we have to use `ord()`
        if letter != ord("a"):
            scanglitch.append(letter)
        else:
            scanglitch.append(ord("e"))

with open(fileout, "wb") as wr:
    wr.write(prelude)
    wr.write(marker)
    wr.write(bytes(scanglitch))

(我知道替换逻辑可以写成列表理解,但我认为这样会更友好。)


推荐阅读