Estamos tratando de convertir una imagen en datos binarios y viceversa para un proyecto mediante C de programación. Todas las otras soluciones que hemos encontrado en la red, ya sea en C++ o Java. Aquí es el enfoque que hemos probado:

  1. Convertir la imagen en un archivo de texto que contiene datos binarios. Cada uno de los 8 personajes se corresponde con el carácter de bytes cuando la imagen se abre con un editor de texto.

  2. A continuación, tratamos de convertir los datos binarios en sus respectivos caracteres usando un programa en C.

  3. A continuación, abrimos el resultado usando el visor de fotos de Picasa. Obtenemos una imagen no válido.

¿Cómo podemos volver a la imagen original? Aquí está el código que hemos utilizado para convertir la imagen en un archivo de texto:

#include<stdio.h>
#include<conio.h>

void main()
{
  clrscr();
  FILE *fptr;
  FILE *txt;
  int c;

  fptr=fopen("D:\aa.bmp","r");
  txt=fopen("D:\test1.txt","w");

  if(fptr==NULL)
  {
    printf("NOTHING In FILE");
    fclose(fptr);
  }
  else
  {
    printf("success");

    do
    {
      c=fgetc(fptr);
      for(int i=0;i<=7;i++)
      {
        if(c&(1<<(7-i)))
        {
          fputc('1',txt);
        }
        else
        {
          fputc('0',txt);
        }
      }
      //fprintf(txt,"\t");
    }while(c!=EOF);

  }

  fclose(fptr);
  fclose(txt);

  printf("writing over");
  getch();
}

Aquí está el código para convertir el archivo de texto resultante de archivo de imagen completo de caracteres binarios, es decir, un archivo de texto con sólo unos y ceros.

#include<stdio.h>
#include<conio.h>


\The following function converts the ones and zeroes in the text file into a character. 
\For example the text file may have the 8 consecutive characters '1','0','0','0','1','0','0','0'. 
\This converts it into the character equivalent of the binary \value 10001000

char bytefromtext(char* text) 
{
  char result=0;
  for(int i=0;i<8;i++)
  {
    if(text[i]=='1')
    {
      result |= (1<< (7-i) );
    }
  }
  return result;
}

void main()
{
  clrscr();
  FILE *pfile;
  FILE *image;
  char buf[8];
  char c;
  int j=0;

  image=fopen("D:\aa2.bmp","w"); //open an empty .bmp file to
                                  //write characters from the source image file
  pfile=fopen("D:\test1.txt","r");

  if(pfile==NULL)
    printf("error");
  else
  {
    c=fgetc(pfile);

    while(c!=EOF)
    {
      buf[j++]=c;
      if(j==8)
      {
        fputc(bytefromtext(buf),image);
        j=0;
      }
      c=fgetc(pfile);

    }

    fclose(pfile);
    fclose(image);
  }

  getch();
}

Obtenemos una imagen no válido cuando los caracteres se escriben en el .archivo bmp. Cuando abrimos este nuevo archivo con un editor de texto y también el archivo de imagen con un editor de texto, conseguimos los mismos personajes.

  • Manejar datos binarios.
  • Su código no es correcto con respecto a la manipulación de los datos de la imagen. El archivo de mapa de bits tiene una información de encabezado al principio del archivo que contiene información acerca de la imagen. La imagen no es simplemente una colección de 8 bytes que representan las intensidades de los píxeles de la imagen. en.wikipedia.org/wiki/…. Como tal, se modifica el encabezado del archivo inadecuadamente, por lo que el archivo no es válido. Se necesita vaya pasado el encabezado, modificar las intensidades de imagen, a continuación, vuelva a guardar la imagen con el mismo encabezado.
  • Por CIERTO, por favor, deje de usar conio.h. Se considera mala práctica: stackoverflow.com/questions/21329485/…
  • No está haciendo nada a los píxeles. Es la conversión de todos los 8bit valor en 8 1s o 0s, a continuación, convertir de nuevo. Nada se ha modificado y no importa lo de los datos.
  • El uso de fgetc está mal. Estás usando char para mantener el valor devuelto, cuando se devuelve un int. Char no puede mantener todos los 256 valores además de la EF marcador. Usted debe arreglar esto. También compruebe los archivos de diferencias con un hex editor, un editor de texto no ayuda mucho.
  • ah, he leído la fuente demasiado rápido. Pensé que el OP estaba tratando de mostrar binario píxeles… no vi que hubo un intento de reconstrucción usando el mismo razonamiento defectuoso… Así que sí, en teoría esto debería funcionar, pero el uso de fgetc está mal aquí. Gracias!

3 Comentarios

  1. 2

    Imagen de archivo de texto

    fptr=fopen("D:\aa.bmp","r");

    El archivo BMP debe ser abierto en modo binario ("rb") para asegurarse de que los bytes se leen los valores correctamente. El "r" modo se abre el archivo en modo texto, lo que puede provocar que algunos caracteres se conviertan, resultando dañada de salida.

    Por ejemplo, en Windows (o, al menos, DOS), los finales de línea se convierte de "\r\n" a "\n" y el carácter "\x1a" podría ser interpretado como y EOF indicador y truncar su entrada.

    Sistemas tipo UNIX, por otro lado, no hay ninguna diferencia.


    do
    {
      c=fgetc(fptr);
      for(int i=0;i<=7;i++)
      {
        /* ... */
      }
      //fprintf(txt,"\t");
    }while(c!=EOF);

    Este bucle es completamente erróneo. Usted necesita comprobar EOF en la parte superior del bucle. Cuando fgetc() devuelve EOF, tu código va a tomar el EOF valor (normalmente -1), y la salida de la correspondiente ceros y unos, antes de salir del bucle. Esto también va a corromper su salida.

    Lugar, usted debe hacer algo como esto:

    while ((c = fgetc (fptr)) != EOF) {
    {
      /* ... */
    }

    Si usted se siente incómodo con la asignación y comparación de la misma expresión, hay una solución para eso:

    while (1)
    {
      c = fgetc (fptr);
      if (c == EOF)
        break;
      /* ... */
    }

    Nota también de que fgetc() también devuelve EOF en caso de error. Usted debe prueba de esto (if (ferror (fptr))) e informe del problema para el usuario.


    fclose(fptr);
    fclose(txt);

    Que debe comprobar el valor devuelto de fclose() e informe de cualquier error que se devuelve al usuario, al menos en el flujo de salida. En algunos sistemas de archivos, la última salida no se escribirán en el disco hasta que el flujo se cierra, y cualquier error de escritura será informado por fclose(). Ver «¿Cuáles son las razones para comprobar error en close()?» para un iluminando a cuento de lo que puede suceder cuando no.

    Archivo de texto a la imagen de

    image=fopen("D:\aa2.bmp","w"); //open an empty .bmp file to

    Que debe utilizar el modo binario ("wb") como se explicó anteriormente.


    char bytefromtext(char* text) 
    {
      char result=0;
      for(int i=0;i<8;i++)
      {
        if(text[i]=='1')
        {
          result |= (1<< (7-i) );
        }
      }
      return result;
    }

    Que debe uso unsigned char al tratar con datos binarios. Llanura char es signed o unsigned en la elección del proveedor (por ejemplo. proveedor de compilador).

    Si el valor almacenado en result no puede ser representado en un signed char (como 1<<7), el resultado es definido por la implementación. Esto, en teoría, podría corromper su salida. Aunque creo que el código es probable que el trabajo previsto en la mayoría de los casos, usted debe utilizar unsigned char como una cuestión de principio.

    (Esto supone, por supuesto, que char no es mayor de 8 bits, que es generalmente el caso.)


    char c;
    
    /* ... */
    
    c=fgetc(pfile);
    
    while(c!=EOF)
    {
      /* ... */
    
      c=fgetc(pfile);
    }

    Este circuito está mal por alguna otra razón. Si llanura char pasa a ser unsigned, c se nunca comparar de igual a EOF, que siempre tiene un valor negativo. Usted debe usar un int variable, prueba en contra de EOF, y sólo a continuación, utilizar el valor como un valor de carácter.


    fclose(pfile);
    fclose(image);

    Usted debe comprobar los valores de retorno como se mencionó anteriormente.

    Otras cuestiones

    También tengo un par de objeciones con el código.

    • En C, main() siempre devuelve int, y debe devolver un valor apropiado para indicar el éxito o el fracaso. (Esto no se aplica a un independiente del entorno, por ejemplo. un programa en C que se ejecutan sin un sistema operativo.)

    • La sección de comentarios en el segundo programa tiene barras en lugar de las barras. Cuando la publicación de su código, usted siempre debe copiar/pegar para evitar la introducción de nuevos errores.

  2. 1

    Comprobar su modo de escritura para image=fopen("D:\\aa2.bmp","w"); no en binario, abierta en «wb».

    • Sigue recibiendo el mismo problema!
    • Cambiado el w a bm pero todavía no válido imagen
  3. 0

    Este es el código que funciona bien. Probado en raspberryPi3 y gcc.

    bmp a texto

    #include <stdio.h>
    
    int main(int argc, char*argv[]){
    
    FILE *ptr_bmp_in;
    FILE *ptr_text_out;
    int c;
    
    ptr_bmp_in=fopen("panda_input.bmp","rb");
    ptr_text_out=fopen("panda_to_text.txt","w");
    
    if(!ptr_bmp_in)
    {
        printf("Unable to open file\n");
        return 1;
    }
    
    while((c=fgetc(ptr_bmp_in)) != EOF)
        {
            for(int i=0;i<=7;i++)
            {
                if(c&(1<<(7-i)))
                {
                    fputc('1',ptr_text_out);
                }
                else
                {
                    fputc('0',ptr_text_out);
                }
            }
        }
    
    
        fclose(ptr_bmp_in);
        fclose(ptr_text_out);
        printf("Writing done\n");
    
        return 0;
    }

    y texto a bmp

    #include <stdio.h>
    
    
    char bytefromtext(unsigned char* text)
    {   
        char result = 0;
        for(int i=0;i<8;i++)
        {
            if(text[i]=='1')
            {
                result |= (1 << (7-i));
            }
        }
        return result;
    }
    
    int main(int argc, char*argv[]){
    
    FILE *ptr_txt_in;
    FILE *ptr_bmp_out;
    unsigned char buf[8];
    int c;
    int j = 0;
    
    
    ptr_txt_in=fopen("panda_to_text.txt","r");
    ptr_bmp_out=fopen("panda_output.bmp","wb");
    
    
    if(!ptr_txt_in)
    {
        printf("Unable to open file\n");
        return 1;
    }
    
    while((c=fgetc(ptr_txt_in)) != EOF)
        {
            buf[j++] = c;
            if(j==8)
            {
                fputc(bytefromtext(buf),ptr_bmp_out);
                j=0;
            }
        }
    
    
        fclose(ptr_txt_in);
        fclose(ptr_bmp_out);
        printf("Writing done\n");
    
        return 0;
    }

Dejar respuesta

Please enter your comment!
Please enter your name here