Read file in binary

1

Hello, I'm saving a file in binary format and trying to open the same binary. However, I'm not getting the expected result. Here are the writing and reading functions. I am saving a .ppm format image, but when I try to bring it back to ASCII file to read it as text I can only get the header of it; In addition the image is only printed with the same code as the original, in the cases I tested every x rows where rows is the number of columns, ie in a 1024 x 768 image it prints the same as the original every 1024 pixels . PPM Images

   //passa o arquivo para binario
    arquivo = fopen("imagem.bin", "wb");
    fwrite(&tipo, 1, sizeof (tipo), arquivo); //salva o tipo do arquivo
    fwrite(&larg, 1, sizeof (int), arquivo); //salva a largura da imagem
    fwrite(&alt, 1, sizeof (int), arquivo); // salva a altura do arquivo
    fwrite(&max, 1, sizeof (int), arquivo); // salva o valor máximo para cor arquivo

    for (i = 0; i < alt; i++){
        for (j = 0; j < larg; j++){
            fwrite(&imagem[i][j].r, 1 , sizeof (int), arquivo); /*salva as componentes*/
            fwrite(&imagem[i][j].g, 1 , sizeof (int), arquivo); /*do arquivo em forma de*/
            fwrite(&imagem[i][j].b, 1 , sizeof (int), arquivo); /*nova linha para cada cor*/
        }
    }
    fclose(arquivo);

    //abre a imagem em binário somente para leitura
    arquivo = fopen("imagem.bin", "rb");
    fread(code, 1, sizeof(code), arquivo);
    fread(&larg, 1, sizeof(int), arquivo);
    fread(&alt, 1, sizeof(int), arquivo);
    fread(&max, 1, sizeof(int), arquivo);

    for (i = 0; i < alt; i++){
        for (i = 0; i < larg; i++){
            fread(&imagem[i][j].r, 1, sizeof(int), arquivo);
            fread(&imagem[i][j].g, 1, sizeof(int), arquivo);
            fread(&imagem[i][j].b, 1, sizeof(int), arquivo);
        }
    }
    fclose(arquivo);
    
asked by anonymous 12.11.2014 / 01:04

1 answer

3

You are saving a bit pattern representing numbers. However, in PPM format, you should save the numbers as text.

That is, use fprintf instead of fwrite . For reading, you can try to use fscanf or fgets .

EDIT:

In your case, since you are using P6, it is a hybrid format. The header is text, but the payload is binary. According to this specification :

  
  • A "magic number" for identifying the file type. A ppm image's magic number is the two characters "P6".
  •   
  • Whitespace (blanks, TABs, CRs, LFs).
  •   
  • A width, formatted as ASCII characters in decimal.
  •   
  • Whitespace.
  •   
  • A height, again in ASCII decimal.
  •   
  • Whitespace.
  •   
  • The maximum color value (Maxval), again in ASCII decimal. Must be less than 65536 and more than zero.
  •   
  • A single whitespace character (usually a newline).
  •   
  • The raster of Height rows, in order from top to bottom. Each row consists of Width pixels, in order from left to right. Each pixel is a triplet of red, green, and blue samples, in that order. Each sample is represented in binary by either 1 or 2 bytes. If the Maxval is less than 256, it is 1 byte. Otherwise, it is 2 bytes. The most significant byte is first.
  •   

    Translating to Portuguese:

      
  • A "magic number" to identify the file type. The magic number of a ppm image is the two "P6" characters.
  •   
  • Whitespace (whites, TABs, CRs, LFs).
  •   
  • The width, formatted in decimal ASCII characters.
  •   
  • Blanks.
  •   
  • The height, again in decimal ASCII.
  •   
  • Blanks.
  •   
  • The maximum value of the color (Maxval), again in decimal ASCII. It should be less than 65536 and more than zero.
  •   
  • A single white space character (usually a line break).
  •   
  • A rasterization with a number of rows equal in height, from top to bottom. Each line consists of a number of pixels equal to width, from left to right. Each pixel contains a triple of the red, green, and blue samples in that order. Each sample is represented purely in binary by 1 or 2 bytes. If the Maxval is less than 256, it is 1 byte. Otherwise, it is 2 bytes. The most significant byte is the first.
  •   

    In conclusion, you must change the part that writes and read the heading to use numbers as text. The reading part is more complex due to the fact that you have to skip an arbitrary amount of whitespace, ignore comments and have to do the text to number conversion, and decide whether each sample has 1 or 2 bytes. But since you claim that you have already done so, then it should be easy.

        
    12.11.2014 / 01:09