问题写PNM P6 [英] Issues writing PNM P6

查看:230
本文介绍了问题写PNM P6的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个程序,它在两个重复PNM P6的文件,提出的第一个文件的存储到缓冲区中,创建了一个黄色的对角线,并将结果写入到第二个文件。当运行它,则输出文件被破坏,不能被显示。看着它缺少的三条线应该是在顶部输出的时候,我注意到:

  P6
1786 1344
255

我不知道如何以编程方式确保这些线保持在code - 我想不通为什么他们甚至被摆在首位覆盖

当我手动添加这些行到输出,该文件将不再损坏。然而,没有出现黄色的对角线。是同一个问题的这部分,还是有别的东西,我应该考虑固定?

我的code:

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;typedef结构
{
    unsigned char型红色,绿色,蓝色;
} iPixel;typedef结构
{
    INT X,Y;
    iPixel *数据;} 图片;图片 *
ReadImage(字符*文件名)
{
    FILE * F = FOPEN(文件名,RB);
    图像* IMG = NULL;
    CHAR magicNum [128];
    INT宽度,高度,MAXVAL;    如果(F == NULL)
    {
        fprintf中(标准错误,无法打开文件%s \\ n,文件名);
        返回NULL;
    }    的fscanf(F%s \\ n%D \\ n%d个\\ N,magicNum,&安培;宽度和放大器,身高和放大器; MAXVAL);
/ *
    的printf(魔NUM =%s的宽度=%d个,身高=%d个,MAXVAL =%d个\\ N,
            magicNum,宽度,高度,MAXVAL)
;
* /
    如果(STRCMP(magicNum,P6)!= 0)
    {
        fprintf中(标准错误,无法从文件%s读,因为它不是类型P6 \\ n的PNM文件,文件名);
        返回NULL;
    }    IMG =(图像*)malloc的(的sizeof(图片));
    IMG - > X =宽度;
    IMG - > Y =高度;
    IMG - >数据=(iPixel *)malloc的(IMG - > X * IMG - > Y *的sizeof(iPixel));    FREAD(IMG - >数据的sizeof(iPixel),宽*高,F);    FCLOSE(F);
    返回IMG;}无效WriteImage(图片* IMG,字符*文件名)
{
    FILE * F = FOPEN(文件名,世行);    FWRITE(img->数据的sizeof(iPixel),img-> X * img-> Y,F);
    FCLOSE(F);
}图片 *
YellowDiagonal(图像*输入)
{    INT I,J;    对于(i = 0; I<输入 - > X;我++)
    {
        为(J = 0; J<输入 - > Y; ​​J ++)
        {
            如果(我== j)条
            {
                输入 - >数据.red = 255 [I]
                输入 - >数据[I]。绿色= 255;
                输入 - >数据[I]的.blue = 0;
            }
        }
    }    返回输入;
}INT主(INT ARGC,CHAR *的argv [])
{
    如果(argc个!= 3)
    {
        fprintf中(标准错误,用法:./3A_c.c<输入图像文件><输出的图像文件> \\ n);
        出口(EXIT_FAILURE);
    }        图像* IMG;        IMG = ReadImage(的argv [1]);
        fprintf中(标准错误,读\\ n);
        YellowDiagonal(IMG);
        fprintf中(标准错误,对角线\\ n);
        WriteImage(IMG,ARGV [2]);
        fprintf中(标准错误,写\\ n);
}


解决方案

小心的的正是你是相同的格式的阅读的。该PNM格式明确和您正确阅读。然而,在写程序有一对夫妇的错误:


  1. 打开一个文件,WWB它截断为0字节;

  2. 最好的做法是经常检查的fopen 成功;

  3. 阅读实际的ASCII数据可以使用的fscanf 完成,二进制数据与 FREAD 。同样,写ASCII应与再做fprintf中,只二进制数据与 FWRITE

  4. 如果你想确保你写同样的数据,你之前阅读,你需要的地方保存。在 MAXVAL 变量读,但不能保存的,所以我不能把它写回。但是,它不是一个的巨大的问题,因为你的code的其余部分假定图像R8G8B8无论如何,所以 MAXVAL 应始终 255

下面是一个调整 WriteImage 的作品。

 无效WriteImage(图片* IMG,字符*文件名)
{
    FILE * F = FOPEN(文件名,世行);    如果(F == NULL)
    {
        的printf(无法打开%s的编写\\ n!,文件名);
     / *更好的将是:返回-1表示错误,否则为0 * /
        返回;
    }    fprintf中(F,P6 \\ n);
    fprintf中(F,%D \\ n,img-> X,img-> Y);
/ *其实你需要写MAXVAL这里* /
    fprintf中(F,%d个\\ N,255);    FWRITE(img->数据的sizeof(iPixel),img-> X * img-> Y,F);
    FCLOSE(F);
}


通过上面的出路,你现在可以看到你的对角线是不正确的!我不打算解决这个问题(我想没有能够看到发生了什么事在你停​​下脚步你),但这里有几个指针只是引导你:


  • 无需返回一个图像* 如果要更改数据的原位的反正

  • 无需检查的每个的单个像素

  • 检查的坐标像素什么改变...

I'm writing a program that takes in two duplicate PNM P6 files, puts the memory of the first file into a buffer, creates a yellow diagonal line over that, and writes the result to the second file. When I run it, the output file is corrupted and can't be displayed. I noticed when looking at the output that it's missing the three lines that should be at the top:

P6
1786 1344
255

I don't know how to programmatically ensure that those lines stay in the code -- I can't figure out why they're even being overwritten in the first place.

When I manually add those lines to the output, the file is no longer corrupted. However, no yellow diagonal line appears. Is this part of the same issue, or is there something else I should look into fixing?

My code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
    unsigned char red, green, blue;
} iPixel;

typedef struct
{
    int x, y;
    iPixel *data;

} Image;

Image *
ReadImage(char *filename)
{
    FILE *f = fopen(filename, "rb");
    Image *img = NULL;
    char magicNum[128];
    int  width, height, maxval;

    if (f == NULL)
    {
        fprintf(stderr, "Unable to open file %s\n", filename);
        return NULL;
    }

    fscanf(f, "%s\n%d %d\n%d\n", magicNum, &width, &height, &maxval);
/*
    printf("Magic num = %s width = %d, height = %d, maxval = %d\n",
            magicNum, width, height, maxval)
; 
*/
    if (strcmp(magicNum, "P6") != 0)
    {
        fprintf(stderr, "Unable to read from file %s, because it is not a PNM file of type P6\n", filename);
        return NULL;
    }

    img = (Image *) malloc(sizeof(Image));
    img -> x = width;
    img -> y = height;
    img -> data = (iPixel*) malloc(img -> x * img -> y * sizeof(iPixel));

    fread(img -> data, sizeof(iPixel), width*height, f);

    fclose(f);
    return img;

}

void WriteImage(Image *img, char *filename)
{
    FILE *f = fopen(filename, "wb");

    fwrite(img->data, sizeof(iPixel), img-> x * img-> y, f);
    fclose(f);
}

Image *
YellowDiagonal(Image *input)
{

    int i, j;

    for (i = 0; i < input->x; i++)
    {
        for (j=0; j < input->y; j++)
        {
            if (i==j)
            {
                input->data[i].red=255;
                input->data[i].green=255;
                input->data[i].blue=0;
            }
        }
    }

    return input;   
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        fprintf(stderr, "Usage: ./3A_c.c <input image file> <output image file>\n");
        exit(EXIT_FAILURE);
    }

        Image *img;

        img = ReadImage(argv[1]);
        fprintf(stderr, "Read.\n");
        YellowDiagonal(img);
        fprintf(stderr, "Diagonal line.\n");
        WriteImage(img, argv[2]);
        fprintf(stderr, "Write.\n");
}

解决方案

Be careful to write exactly the same format you are reading. The PNM format is well defined, and you are reading it correctly. However, in the writing routine there were a couple of mistakes:

  1. opening a file with "w" or "wb" truncates it to 0 bytes;
  2. best practice is always to check if fopen succeeds;
  3. reading actual ASCII data can be done with fscanf, binary data with fread. Similarly, writing ASCII should be done with fprintf and only binary data again with fwrite.
  4. If you want to make sure you write the same data as you read in before, you need to save it somewhere. The maxval variable is read, but not saved, and so I cannot write it back. However, it is not a huge problem because the rest of your code assumes the image is R8G8B8 anyway, and so maxval should always be 255.

Here is an adjusted WriteImage that works.

void WriteImage(Image *img, char *filename)
{
    FILE *f = fopen(filename, "wb");

    if (f == NULL)
    {
        printf ("Unable to open '%s' for writing!\n", filename);
     /* better would be: "return -1" to indicate an error, 0 otherwise */
        return;
    }

    fprintf (f, "P6\n");
    fprintf (f, "%d %d\n", img->x, img->y);
/*  actually you need to write 'maxval' here */
    fprintf (f, "%d\n", 255);

    fwrite(img->data, sizeof(iPixel), img->x * img->y, f);
    fclose(f);
}


With the above out of the way, you can now see your 'diagonal line' is not correct! I'm not going to fix that (I suppose not being able to see what happened stopped you in your tracks), but here are a few pointers just to guide you:

  • no need to return an Image * if you are changing data in situ anyway
  • no need to check every single pixel
  • check the coordinates of what pixels are changed ...

这篇关于问题写PNM P6的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆