Read file in binary

Asked

Viewed 2,424 times

1

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

   //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);

1 answer

3


You are saving a bit pattern that represents numbers. However, in PPM format, you must save the numbers as text.

That is, use fprintf instead of fwrite. For reading, you can try using a fscanf or a 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:

  1. A "Magic number" for Identifying the file type. A ppm image’s Magic number is the two characters "P6".
  2. Whitespace (Blanks, Tabs, Crs, Lfs).
  3. A width, Formatted as ASCII characters in decimal.
  4. Whitespace.
  5. A height, Again in ASCII decimal.
  6. Whitespace.
  7. The Maximum color value (Maxval), Again in ASCII decimal. Must be Less than 65536 and more than zero.
  8. A single whitespace Character (usually a newline).
  9. A 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 Pure 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 into Portuguese:

  1. A "magic number" to identify the file type. The magic number of a ppm image is the two characters "P6".
  2. White spaces (white, Tabs, Crs, Lfs).
  3. Width, formatted in decimal ASCII characters.
  4. Blanks.
  5. Height, again in ASCII decimal.
  6. Blanks.
  7. The maximum color value (Maxval), again in ASCII decimal. Must be less than 65536 and more than zero.
  8. A single blank character (usually a line break).
  9. A rasterization with a number of lines equal to height, from top to bottom. Each line consists of a number of pixels equal to the width, from left to right. Each pixel contains a triple of the red, green and blue samples in this order. Each sample is represented purely in binary by 1 or 2 bytes. If Maxval is less than 256, it is 1 byte. Otherwise, it is 2 bytes. The most significant byte is the first.

In conclusion, you should change the part that writes and reads the header 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 convert text to number, and decide whether each sample has 1 or 2 bytes. But since you claim you’ve already done it, then it should be easy.

  • So, in ppm format when P3 is specified it is by text, but the P6 parameter indicates that it is saved in binary, so much so that the implementation of it by text I have ready.

  • @pmargreff Okay, I edited the answer, see if it’s cool now.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.