Editar ficheros binarios con Python

Agrupa todas las consultas sobre los lenguajes de programacion como C, C++, Python, Java ...

Editar ficheros binarios con Python

Notapor Metator de Arkalot » Mié Nov 19, 2008 8:19 pm

Pues eso, necesito saber como editar un fichero byte por byte,
por ejemplo, escribir en el los sigientes numeros:
00000001, 00000010, 00000011 (1, 2, 3, etc)
Y también necesito leer byte por byte y convertirlos en enteros Python

Habia encontrado una función que hace algo similar:
Código: Seleccionar todo
import struct

binfile = open("data.bin", "wb")
data = struct.pack('hhl', 1, 2, 3)
binfile.write(data)


El problema es que no se que es ese argumento 'hhl', ademas de
que en realidad me escribe tres bytes vacios (00000000) antes
de escribir el numero 1 en binario (00000001).

Lo que estoy haciendo es un formato de fichero para comprimir
imagenes. Ya tengo el algoritmo, pero no se como editar un binario:
por ejemplo, voy a usar pygame para obtener los valores RGB de
una imagen, pixel por pixel, y quiero ir poniendo esos tres valores en
binario:

ROJO = 11111111, 00000000, 00000000
AZUL = 00000000, 00000000, 11111111

Ademas de otras cosas, pero eso es el primer paso.
Espero puedan ayudarme a entender este módulo, u otro si es necesario :D
Avatar de Usuario
Metator de Arkalot
 
Mensajes: 34
Registrado: Mié Abr 23, 2008 2:17 am
Ubicación: México ñ_ñ !!

Re: Editar ficheros binarios con Python

Notapor hugoruscitti » Jue Nov 20, 2008 1:51 pm

Metator de Arkalot escribió:El problema es que no se que es ese argumento 'hhl', ademas de
que en realidad me escribe tres bytes vacios (00000000) antes
de escribir el numero 1 en binario (00000001).


Por lo que se ve, el módulo struct sirve para trasladar tipos de datos
nativos de python a estructuras de C, se vé muy bueno, no lo conocía.

Ahora bien, tal vez te esté faltando como dato tener la documentación
de esté módulo: En python existe una función que te da información
sobre cualquier objeto de python, la función help.

Por ejemplo, ejecutando lo siguiente desde el intérprete interactivo
se obtiene toda la ayuda el módulo:

import struct
help(struct)

ahí veo para qué se usa el módulo, y leyendo un poco mas veo que los
parámetros "hhl" de tu función no responden a lo que quieres hacer, cada
caracter de esa cadena significa el tipo de dato destino que quieres
asignar a tus números.

Tu sentencia sería algo como:

data = struct.pack('hhl', 1, 2, 3

crear una estructura donde

1 se convierte a: short
2 se convierte a: short
3 se convierte a: long

tal vez te sirva probar con valores como "x" (int), o "X" (unsigned int).

En fin, leer la ayuda del módulo es primordial.

Metator de Arkalot escribió:Lo que estoy haciendo es un formato de fichero para comprimir
imagenes. Ya tengo el algoritmo, pero no se como editar un binario:
por ejemplo, voy a usar pygame para obtener los valores RGB de
una imagen, pixel por pixel, y quiero ir poniendo esos tres valores en
binario:

ROJO = 11111111, 00000000, 00000000
AZUL = 00000000, 00000000, 11111111

Ademas de otras cosas, pero eso es el primer paso.
Espero puedan ayudarme a entender este módulo, u otro si es necesario :D



Una sugerencia, tal vez te sirva usar el método "pygame.image.tostring" para
obtener todos los bytes de una imagen en formato de cadena; esto te evita
leer uno a uno cada pixel. Pero claro, todo depende de lo que te motive a
construir tu programa.

Ah, también te dejo otro dato, existe un módulo llamado cPickle que te permite
tomar cualquier estructura de memoria de python y volcarla a disco o
recuperarla desde ahí, es bastante útil.

En fin, ojalá te resulte útil mi comentario. Y disculpa si me fui un poco
del tema en cuestión...

Saludos.
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina

Joer, lo he conseguido y casi me doy un tope XD

Notapor Metator de Arkalot » Jue Nov 20, 2008 6:51 pm

Aun no se como es que di con la respuesta:
https://arco.inf-cr.uclm.es/pipermail/python/2005-March/000138.html

Era tan sencillo, eso lo había visto desde que comencé a estudiar Python.
El modulo struct es demasiado por ahora, al menos para mi.

Para escribir un byte directamente usé algo distinto:

Código: Seleccionar todo
import pygame
pygame.init()

imagen = pygame.image.load("imagen.png")
cadena = pygame.image.tostring(imagen, 'RGB')
# esto devuelve una cadena, pero solo imprime los caracteres
# si tienen un correspondiente en la tabla ACSII

binfile = open("data.bin", "w")

for car in cadena:
    binfile.write(car)
binfile.close()


El archivo resultante tiene exactamente 12 bytes, (la imagen era
un pequeño png de 2x2 para poder examinar cada pixel en un
editor hexadecimal)

Así por ejemplo, el primer color de la imagen era rojo (255, 0, 0), luego
el verde y después el azul. Al escribirlo (write) daba directamente:

111111110000000000000000|000000001111111100000000|000000000000000011111111

Sip, eso era exactamente o que buscaba, pues write solo acepta una cadena.

Así pues, para poner un numero que no este en la tabla a ASCII, como
el 255, ahora se que puedo poner:

Código: Seleccionar todo
>>> write(‘\xff’) # XD
# Para leerlo, solo basta con poner:
>>> ord(binfile.readline(1)) # Leé un solo byte y lo convierte en entero
255


:D

Ahora que se como escribir y leer un byte sin entrar en orden de
bytes y demás jaladas, me dedicare a programar mi algoritmo,
aquí mismo les cuento como me salió.
Avatar de Usuario
Metator de Arkalot
 
Mensajes: 34
Registrado: Mié Abr 23, 2008 2:17 am
Ubicación: México ñ_ñ !!


Volver a Sobre lenguajes de programación

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados

cron