c++ - 反转 PBM 图像的位 while vs for 循环

标签 c++ image-processing file-format pbm netpbm

我正在尝试翻转只有纯黑色和纯白色的简单 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

如您所见,倒置图像中仅打印了一半行。

如果我将 write_pbm.cppinvert() 的嵌套循环替换为

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 循环的情况下会给出错误的输出?

感谢阅读本文,请提供您宝贵的回复。

最佳答案

查看您的输入文件,似乎每个有意义的字符(即 '0''1')后跟一个空格。

在正在运行的 while 循环中,您可以根据需要读取尽可能多的字符,直到文件末尾,只需反转正确的字符并复制意外的字符。所以一切都被处理了。

在嵌套的 for 循环中,您正在读取与图片尺寸相对应的确切字符数,即 10*10。考虑到输入文件的布局,您因此只能读取 100 个字符,即 50 个 '1''0' 和 50 个空格。所以你只处理一半的输入。

不相关:您的代码使用 C++ header ,但所有其他代码只是普通的 C。在 C++ 中,您应该考虑使用 fstream 来读取您的文件,而不是 C 遗留 FILE* API。

关于c++ - 反转 PBM 图像的位 while vs for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55332574/

相关文章:

android - OpenCV:转换MatOfDMatch,MatOfPoint2f,MatOfKeypoint,查找FundamentalMatrix的方法

c++ - 在 C++ 中打开/解码 Zork 保存文件(Quetzal 格式)

file-format - iNES 格式的 ROM 库有多大?

java - 可访问、跨平台、相关的 UI 框架?

c++ - VS Intellisense 如何在编辑头文件时从 stdafx.h 中找到定义?

c# - 速度 - 将位图数据复制到数组中还是直接使用它?

c# - 在 C# 中加速矩阵加法

c++ - C++ 中的开源 DXF 解析器

c++ - 字符串[包含整数]的乘法,输出也存储在字符串中,如何?

c++ - 没有成员可用于声明为类变量的对象