我正在开发一个转换器,将 PPM 从 P6(二进制)转换为 P3 (ASCII)。 由于 PPM 是一种原始格式,我认为我不会遇到质量损失,但由于某些无法解释的原因,这是在转换时发生的情况:
原始图片:
转换后的图像:
这是我为作业编写的算法:
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 倍。
最佳答案
@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 channel ))不是代码的“.ppm”。可能的大小问题是原始 .ppm 文件被保存为 .jpg,而生成的 .ppm 文件被保存为 .png。 .jpg 是一种有损格式,它只是简单地提取了一些数据,并且能够生成比 .png 文件更小的文件,后者保留了所有内容。
关于c - PPM 将二进制转换为 ASCII - 无法解释的质量损失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18341143/