x20
x20

Reputation: 17

Encoding error in Python

Trying to make an encode process but have an error line:

Look at my whole fuction ,please, for the whole getting it. I think it isn't big enough.

Trying to add the header to the file data:

#Add the header to the file data
    headerdata = struct.pack("4s"+\
                             "I"+\
                             str(Header.MAX_FORMAT_LENGTH)+"s",header.magicnum, header.size, header.fformat)
    filebytes = headerdata + data

Have an error:

str(Header.MAX_FORMAT_LENGTH)+"s",header.magicnum, header.size, header.fformat) struct.error: argument for 's' must be a bytes object

I was trying to change it:(this line, addin 'b')

str(Header.MAX_FORMAT_LENGTH)+b"s",header.magicnum, header.size, header.fformat)

Have another error:

str(Header.MAX_FORMAT_LENGTH)+b's',header.magicnum, header.size, header.fformat) TypeError: must be str, not bytes

the whole fucnton:

def encode(image, data, filename, encryption=False, password=""):
    im = Image.open(image)
    px = im.load()

    #Create a header
    header = Header()
    header.size = len(data)
    header.fformat = "" if (len(filename.split(os.extsep))<2)\
                     else filename.split(os.extsep)[1]

    #Add the header to the file data
    headerdata = struct.pack("4s"+\
                             "I"+\
                             str(Header.MAX_FORMAT_LENGTH)+"s",header.magicnum, header.size, header.fformat)
    filebytes = headerdata + data

    #Optional encryption step
    if encrypt:
        if password:
            filebytes = encrypt(filebytes, password,\
                                padding=im.width*im.height - len(filebytes))
        else:
            print ("Password is empty, encryption skipped")

    #Ensure the image is large enough to hide the data
    if len(filebytes) > im.width*im.height:
        print ("Image too small to encode the file. \
You can store 1 byte per pixel.")
        exit()

    for i in range(len(filebytes)):
        coords = (i%im.width, i/im.width)

        byte = ord(filebytes[i])

        px[coords[0], coords[1]] = encode_in_pixel(byte, px[coords[0],\
                                                            coords[1]])

    im.save("output.png", "PNG")

Upvotes: 2

Views: 173

Answers (2)

jacoblaw
jacoblaw

Reputation: 1283

Code

since you said they are all strings, here you go

headerdata = struct.pack("4s"+\
                             "I"+\
                             str(Header.MAX_FORMAT_LENGTH)+"s",header.magicnum.encode(), int(header.size), header.fformat.encode())

This should work for the formats and types you want

Explanation

According to this, and specifically section 7.1.2.2, we can find the types needed as arguments for the following format characters:

-----------------------------------------
|Formatting Character | Type (in python)|
-----------------------------------------
|s                    | integer         |
-----------------------------------------
|I                    | bytes           |
-----------------------------------------

and since the data you want to format is of type str, we need to change it.

Lets start with making a str to and integer since it's the simplest.

>>> x = '123'
>>> type(x)
str
>>> y = int(x)
>>> type(y)
int

Easy, all we need to do is call int() on our string.

Next up is turning a string into bytes. We use strings encode() method to do this (documentation)

>>> x = '123'
>>> type(x)
str
>>> y = e.encode()
>>> type(y)
bytes
>>> print(y)
b'123'

Upvotes: 0

K. Nielson
K. Nielson

Reputation: 191

Your original code was correct, except that the type of header.magicnum was unexpected. Your code snippet should read

#Add the header to the file data
    headerdata = struct.pack("4s"+\
                             "I"+\
                             str(Header.MAX_FORMAT_LENGTH)+"s","{:04d}".format(header.magicnum).encode('UTF-8'), header.size, header.fformat)
    filebytes = headerdata + data

or some other suitable format code and encoding that turns header.magicnum into your expected result.

Upvotes: 1

Related Questions