views:

2152

answers:

3

Hi there... I don't know if the question title is correctly set. I'm trying to read a BMP file in python. I know the first two bytes indicate the bmp firm. Next 4 bytes are the file size. When I excecute:

fin = open("hi.bmp", "rb")
firm = fin.read(2)  
file_size = int(fin.read(4))  

I get

ValueError: invalid literal for int() with base 10: 'F#\x13'

What I want to do is reading those 4 bytes as an integer... It seems python is reading them as characters and returning a string, which cannot be converted to an integer. How can I do this correctly?
Thanks!

+8  A: 

The read method returns a sequence of bytes as a string. To convert from a string byte-sequence to binary data, use the built-in struct module: http://docs.python.org/library/struct.html.

import struct

print struck.unpack('i', fin.read(4))

Note that unpack always returns a tuple, so struct.unpack('i', fin.read(4))[0] gives the integer value that you are after.

You should probably use the format string '<i' (< is a modifier that indicates little-endian byte-order and standard size and alignment - the default is to use the platform's byte ordering, size and alignment). According to the BMP format spec, the bytes should be written in Intel/little-endian byte order.

codeape
Instead of writing `i = struct.unpack(...)[0]` I often write `i, = struct.unpack(...)`
Otto Allmendinger
+3  A: 

As you are reading the binary file, you need to unpack it into a integer, so us struct module for that

import struct
fin = open("hi.bmp", "rb")
firm = fin.read(2)  
file_size, = struct.unpack("i",fin.read(4))
Anurag Uniyal
struct.unpack returns a tuple
luc
@luc, thanks, fixed
Anurag Uniyal
+2  A: 

Except struct you can also use array module

import array
values = array.array('l') # array of long integers
values.read(fin, 1) # read 1 integer
file_size  = values[0]
Nick D
Good point. But this solution is not as flexible as that of the struct module, since all elements read through values.read() must be long integers (it is not convenient to read a long integer, a byte, and then a long integer, with the array module).
EOL
I agree. `array` is an efficient way to read a binary file but not very flexible when we have to deal with structure, as you correctly mentioned.
Nick D