1

我正在开发一个转换器,将 PPM 从 P6(二进制)转换为 P3(ASCII)。由于 PPM 是一种原始格式,我认为我不会遇到质量损失,但由于某些无法解释的原因,转换时会发生这种情况:

原图: PP6

转换后的图像: PP3

这是我为这项工作编写的算法:

int convertP6toP3(char* fileName)
{
    FILE *src, *dest;
    char *outputFilename;
    char magicNumber[3];
    int height, width, depth;
    unsigned char red, green, blue;
    int i, j, widthCounter = 1;

    if (checkFileExists(fileName) == FALSE)
    {
        printf("- Given file does not exists!\n");
        return ERROR;
    }

    else
        src = fopen(fileName, "rb");

    // create output filename #MUST FREE ALLOCATED MEMORY#
    outputFilename = getOutputFilename(fileName, ".p3.ppm");
    // REMOVE + AFTER TESTING
    dest = fopen(outputFilename, "w+");

    // check that the input file is actually in P6 format
    fscanf(src, "%s", magicNumber);
    if (strcmp(magicNumber, "P6") != 0)
        return ERROR;
    fscanf(src, "\n%d %d\n%d\n", &width, &height, &depth);

    fprintf(dest, "P3\n");
    fprintf(dest, "#P3 converted from P6\n");
    fprintf(dest, "%d %d\n%d\n", width, height, depth);;
    for (i = 0; i < width*height; i++)
    {

        for (j = 0;  j < 3; j++)
        {
            fread(&red, 1, 1, src);
            fread(&green, 1, 1, src);
            fread(&blue, 1, 1, src);
        }

        for (j = 0;  j < 3; j++)
            fprintf(dest, "%d %d %d ", red, green, blue);

        if (widthCounter == width)
        {
            fprintf(dest, "\n");
            widthCounter = 1;
        }

        else
            widthCounter++;
    }

    free(outputFilename);
    fclose(src);
    fclose(dest);
    return TRUE;
}

为什么我会遇到这种质量损失?

编辑:使用记事本打开 GIMP 转换的输出文件时,我发现我的转换器的样本(红绿或蓝色值)是 GIMP 的 3 倍。

4

2 回答 2

4

@Quaker 拥有大部分

“for (j = 0; j < 3; j++) 循环都是问题的根源,它们会打印每个像素三次,从而导致图像错误。”

这解释了质量的损失。3个像素被误读

for (j = 0;  j < 3; j++) { fread(&red, 1, 1, src); ...

前 2 个像素的值被丢弃。第 3 个像素被写入 3 次

for (j = 0;  j < 3; j++) fprintf(dest, "%d %d %d ", red, green, blue);

尺寸问题“图像错误”可能是其他问题。提供的图片(原始图片为 jpeg)和生成的图片(具有透明度的 png(alpha 通道))不是代码的“.ppm”。可能的大小问题是原始 .ppm 文件保存为 .jpg 而生成的 .ppm 文件保存为 .png。.jpg 是一种有损格式,只是简单地删除了一些数据,并且能够制作比 .png 文件更小的文件,后者保留了所有内容。

于 2013-08-20T20:39:10.987 回答
1

这两个for (j = 0; j < 3; j++)循环都是问题的根源,它们会打印每个像素三次,这会导致图像错误。

于 2013-08-20T17:41:39.150 回答