Инвертирование битов изображения PBM, в то время как для цикла
Я пытаюсь перевернуть цвет пикселей простого изображения в формате pbm, которое имеет только чистый черный и чистый белый. Я сам генерирую изображение и затем читаю его, а затем переворачиваю биты и сохраняю как сгенерированное изображение, так и инвертированное изображение.
Вот мой код (write_pbm.cpp) -
#include "headers/write_pbm.h"
int width_pbm, height_pbm;
void input_sample_dim(){
printf("Enter the width and height of image to create = ");
scanf("%d %d", &width_pbm, &height_pbm);
}
void create_sample_image(){
FILE *fp;
fp = fopen("sample.pbm", "wb");
fprintf(fp, "P1\n");
fprintf(fp, "# myfile.pbm\n");
fprintf(fp, "%d %d\n", width_pbm, height_pbm);
for (int i = 1; i <= height_pbm; i++)
{
for (int j = 1; j <= width_pbm; j++)
{
if (j == i || (width_pbm - j + 1 == i))
fprintf(fp, "0");
else
fprintf(fp, "1");
if (j == width_pbm)
fprintf(fp, "\n");
else
fprintf(fp, " ");
}
}
fclose(fp);
}
void invert (){
printf("\tinverting the image\nturning black pixels white and white pixels black\n");
FILE *fp = fopen("sample.pbm", "rb");
while(fgetc(fp) != '\n');
while(fgetc(fp) != '\n');
while(fgetc(fp) != '\n');
FILE *fp_inv;
fp_inv = fopen("inverted.pbm", "wb");
fprintf(fp_inv, "P1\n");
fprintf(fp_inv, "# inverted.pbm\n");
fprintf(fp_inv, "%d %d\n", width_pbm, height_pbm);
for (int i = 1; i <= height_pbm; i++){
for (int j = 1; j <= width_pbm; j++){
char ch = fgetc(fp);
if (ch == '1')
fputc('0', fp_inv);
else if (ch == '0')
fputc('1', fp_inv);
else
fputc(ch, fp_inv);
}}
fclose(fp);
fclose(fp_inv);
}
Ниже приведен заголовок, который я включаю (write_pbm.h)
#ifndef Write_PBM_H
#define Write_PBM_H
#include <cstdio>
#include <iostream>
void create_sample_image(void);
void input_sample_dim(void);
void invert (void);
extern int width_pbm, height_pbm;
#endif
Ниже мой главный -
#include "write/PBM/headers/write_pbm.h"
int main(){
input_sample_dim();
printf("writing sample image\n");
create_sample_image();
printf("sample image with dimenstions %d by %d created\n", width_pbm, height_pbm);
invert();
}
Таким образом, я делаю V-образный вид шаблона, а затем инвертирую цвета и сохраняю как созданное изображение, так и инвертированное изображение.
Предположим, мы предоставляем вход 10 10
тогда файл sample.pbm
похоже
P1
# myfile.pbm
10 10
0 1 1 1 1 1 1 1 1 0
1 0 1 1 1 1 1 1 0 1
1 1 0 1 1 1 1 0 1 1
1 1 1 0 1 1 0 1 1 1
1 1 1 1 0 0 1 1 1 1
1 1 1 1 0 0 1 1 1 1
1 1 1 0 1 1 0 1 1 1
1 1 0 1 1 1 1 0 1 1
1 0 1 1 1 1 1 1 0 1
0 1 1 1 1 1 1 1 1 0
а также inverted.pbm
выглядит так
P1
# inverted.pbm
10 10
1 0 0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0 1 0
0 0 1 0 0 0 0 1 0 0
0 0 0 1 0 0 1 0 0 0
0 0 0 0 1 1 0 0 0 0
как вы можете видеть, что только половина строк печатается в перевернутом изображении.
Если я заменю вложенные циклы invert()
из write_pbm.cpp
с
char ch;
while(!feof(fp))
{
char ch = fgetc(fp);
if (ch == '1')
fputc('0', fp_inv);
else if (ch == '0')
fputc('1', fp_inv);
else
fputc(ch, fp_inv);
}
тогда это дает правильный вывод в inverted.pbm
файл, который
P1
# inverted.pbm
10 10
1 0 0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0 1 0
0 0 1 0 0 0 0 1 0 0
0 0 0 1 0 0 1 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 1 0 0 1 0 0 0
0 0 1 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0 1 0
1 0 0 0 0 0 0 0 0 1
\FF
Я делаю то же самое через вложенные циклы и цикл while, тогда почему он дает неправильный вывод в случае вложенных циклов for?
Спасибо, что прочитали это, пожалуйста, предоставьте ваш ценный ответ.
1 ответ
Глядя на ваш входной файл, кажется, что каждый значащий символ (т.е. '0'
или же '1'
) следует пробел.
в while
Цикл, который работает, вы читаете столько символов, сколько нужно, до конца файла, просто инвертируя правильные символы и копируя неожиданные символы. Так что все обрабатывается.
Во вложенном for
циклы, вы читаете точное количество символов, соответствующее размерам изображения, так что 10*10. Принимая во внимание структуру входного файла, вы, следовательно, читаете только 100 символов, поэтому 50 '1'
или же '0'
и 50 мест. Таким образом, вы обрабатываете только половину ввода.
Несвязанный: ваш код использует заголовок C++, но все остальное - просто C. В C++ вы должны рассмотреть возможность использования fstream
читать ваши файлы, а не наследие CFILE*
API.