Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # -*- encoding: utf-8 -*-
- # Written by kenkeiras
- #########################################################################
- # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- # Version 2, December 2004
- #
- # Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
- #
- # Everyone is permitted to copy and distribute verbatim or modified
- # copies of this license document, and changing it is allowed as long
- # as the name is changed.
- #
- # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- # TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- #
- # 0. You just DO WHAT THE FUCK YOU WANT TO.
- #########################################################################
- #
- # Convierte una tupla en un array
- def tuple2arr( t ):
- a = []
- for i in t:
- a.append( i )
- return a
- # Convierte un array en una tupla
- def arr2tuple( a ):
- t = ( )
- for i in a:
- t += ( i, )
- return t
- # Manejo de bits
- # Cambiar el LSB
- def changeLSB( byt, bt ):
- if ( bt & 1 ) > 0:
- byt |= 1
- else:
- byt &= 0xFE
- return byt
- # Descompone un byte en array de bits
- def decomposeByte( bt ):
- out = []
- i = 7
- nbt = ord( bt )
- while i >= 0 :
- out.append( nbt / ( 2**i ) )
- nbt = nbt % ( 2**i )
- i -= 1
- return out
- # Código en si
- import sys, os
- try:
- from PIL import Image
- except:
- print >>sys.stderr, "Necesitas PIL"
- print >>sys.stderr, "[ http://www.pythonware.com/products/pil/ ]"
- exit( 0 )
- # Comprueba los argumentos
- if ( len( sys.argv ) < 4 ):
- print >>sys.stderr, sys.argv[ 0 ], "<imágen> <archivo> <salida>"
- exit( 0 )
- # Intenta leer la imágen
- img = None
- try:
- img = Image.open( sys.argv[ 1 ] )
- except:
- print >>sys.stderr, "Error leyendo", sys.argv[ 1 ]
- exit( 1 )
- # Lee el archivo a introducir
- f = None
- try:
- f = open( sys.argv[ 2 ], "rb" )
- except:
- print >>sys.stderr, "Error leyendo", sys.argv[ 2 ]
- exit( 1 )
- # Muestra el espacio disponible
- fsize = os.path.getsize( sys.argv[ 2 ] )
- dim = img.size
- avail_size = ( dim[ 0 ] * dim [ 1 ] * len( img.getbands( ) ) ) / 8
- print "Tamaño del archivo:", fsize, "bytes"
- print "Imágen:"
- print dim[ 0 ], "x", dim[ 1 ]
- print avail_size , "bytes"
- print float( avail_size ) / ( 1 << 10 ), "Kb"
- if ( avail_size < fsize ):
- print >>sys.stderr, "No hay espacio suficiente"
- exit( 2 )
- # Carga todo en memoria ( más rápido para cambiar muchos pixels )
- fst_img = img.load( )
- x = 0 # Posición X
- y = 0 # Posición Y
- msg = f.read(1) # Byte actual
- inp = [] # Bits de entrada
- bpp = len( img.getbands( ) ) # Bytes por pixel
- # Mientras quede mensaje
- while ( len( msg ) > 0 ):
- # Se añade a la lista el mensaje
- inp = inp + decomposeByte(msg[0])
- # Mientras queden datos de entrada
- while ( len ( inp ) > 0 ):
- # Si no hay suficientes para un pixel, se leen
- if ( len ( inp ) < bpp ):
- msg = f.read( 1 )
- if len( msg ) < 1 :
- break
- inp = inp + decomposeByte( msg[ 0 ] )
- # Se lee la siguiente tupla
- nxt_pix = tuple2arr( fst_img[ x, y ] )
- # Para cada byte
- for i in xrange( bpp ):
- # se cambia el LSB
- nxt_pix[ i ] = changeLSB( nxt_pix[ i ], inp.pop( 0 ) )
- # Se guarda la tupla
- fst_img[ x, y ] = arr2tuple( nxt_pix )
- # Y se pasa al siguiente pixel
- x += 1
- if ( x >= dim[ 0 ] ):
- x = 0
- y += 1
- msg = f.read( 1 )
- # Si aún queda algo
- if ( len( inp ) > 0 ):
- # Se lee la siguiente tupla
- nxt_pix = tuple2arr( fst_img[ x, y ] )
- # Para cada byte
- for i in xrange( bpp ):
- if ( len( inp ) < 1 ):
- break
- # se cambia el LSB
- nxt_pix[ i ] = changeLSB( nxt_pix[ i ], inp.pop( 0 ) )
- # Se guarda la tupla
- fst_img[ x, y ] = arr2tuple( nxt_pix )
- # Ya se acabo con el archivo
- f.close()
- # Por último se guarda en la imágen
- img.save( sys.argv[ 3 ] )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement