No se hacen tareas y menos a los estudiantes...
Se resuelven dudas puntuales donde uno se queda atascado. si uno se queda atascado sin siquiera pode rempezar, es un claro indicativo, de que no se ha esforzado demasiado...
De todos modos te pongo los pasos (pasos grandes, luego hay que desmenuzar cada uno en otros más pequeños).
0 - De entrada la imagen de salida no puede ser cualquier formato, debe ser un formato de imagen que no se comprima, ya que el compresor de la imagen sobrescribirá el contenido real (no preserva la imagen original), y por tanto se perderá el código que trates de ocultar. Dicho lo cual, elige un formato sin compresión, por ejemplo BMP.
1 - Lo siguiente es pués tener una especificación del formato, para ser capaz de leer e interpretar la imagen de origen... en realidad te puede bastar con saber como obtener el array de bytes de los píxeles para modificarlos...
2 - Una vez cargada la imagen (hazte a la idea que necesitas 1 píxel por cada 3 bits de tu mensaje), obtén el array de píxeles si los obtienes en bytes, no tienes que desmenuzarlos (separarlos en sus componentes RGB (o RGBA)).
3 - Ya con el array de bytes de los píxeles, construyes varios bucles, uno por cada carácter que debas ocultar y otro interno por cada bit del carácter.
Sobre este mismo bucle, llevas un contador de un bucle 'fantasma' es decir se recorre el bucle de bytes al mismo tiempo que se explora cada bit de los caracteres...
Más o menos así:
Por cada caracter a ocultar
Por cada bit en el carácter
arraypixeles(n) = (arraypixeles(n) and 254 or bit)
n +=1 <---- aumenta el contador de bytes del array
siguiente bit <---- aumenta el contador de bits del carácter
siguiente caracter <---- aumenta el contador de carácteres en la cadena a ocultar
La línea, clave es: arraypixeles(n) = (arraypixeles(n) and 254 or bit)
"arraypixeles(n) and 254", pone el último bit de ese byte a 0, es decir lo borra, porque 254 es una máscara: 11111110, por lo cual, respeta en origen los 7 bits más altos, pero borra el último.
or bit) <---- pone ese bit (el de menor peso en el byte al valor que contiene el bit tratado en el carácter. Si es 1, pone un 1 si es 0, queda tal cual.
4 - Guarda la imagen a fichero. Si tomaste el array de bytes de forma copiada en vez de obtener un puntero al origne, deberás copiar el nuevo ocntenido al destino, antes de guardar la imagen.
Como la imagen es sin compresión, no hay una operación ulterior que borre los bits menos relevantes.
Por qué funciona: Porque el cambio de un bit en un byte apenas si cambia de matiz el color del píxel, además no siempre se cambian los 3 bits (RGB), alguno coincidirá con el bit de origen.
Es buena práctica, al comienzo añadir un textoadicional para que al leer de nuevo, se pueda asegurar de forma rápida si contiene aún nuestor mensaje o no, añadiendo una especie de 'copyright', que tiene más el sentido de 'sigue existiendo'... si tuvieras un conocimiento mayor, yo haría un hash al texto a escribir, y escribiría ese hash, así sabría al final si el texto se ha conservado sin alteración...
Lógicamente deberías realizar la parte inversa, es decir la parte que lee la imnagen y luego recompone el texto con el último bit de cada byte del array de bytes de los píxeles.
mmm... te advierto solo de 3 cosas:
A - Según el formato elegido, pueden sus líneas ser leídas de abajo arriba o de arriba abajo. debe tenerse en cuenta, para que no quede al revés el texto al escribirlo o leerlo y uno crea que 'falló'.
B - Ten encuenta como vas leyendo los bits de los caracteres, eres libre de empezar desde el bit de menos peso primero y acabar en el 7º, o al revés... incluso nada teimpide seguir otro orden diferente, por si alguien intenta leerlos seguidos para descubrir si hay un texto oculto.
C - No uses los bytes del canal alfa, si el formato lo guarda, a veces puede ser ignorado y por tanto podría no ser recuperado.
El resto es tarea tuya. a grandes rasgos tienes el tema bastante claro... Suerte y al tajo, al trabajo.