在unix c中逐字节比较两张图片

时间:2018-05-04 15:00:48

标签: c image file unix compare

我写了这个方法来比较两个文件,特别是图片,并在输出中打印出差异和它是什么。此时,结果是每个字节与另一个字节不同,但图像I比较是相同的。你能帮我吗?这是代码:

void compareFiles(char* path1, char* path2){
    FILE* img1;
    FILE* img2;

    if((img1 = fopen(path1,"r")) == NULL || (img2 = fopen(path2,"r")) == NULL){
        printf("ERROR fopen()\n");
        exit(-1);
    }

    int i=0;
    char buffer1,buffer2;

    int c;
    while ((c=fgetc(img1)) != EOF){
        fread(&buffer1, 1,1, img1);
        fread(&buffer2, 1,1, img2);
        if(buffer1 != buffer2){
            printf("Byte differs\n IMG1: %s, IMG2: %s; Position %d\n",&buffer1,&buffer2,i);
            i++;
        }
    }

    fclose(img1);
    fclose(img2);
}

3 个答案:

答案 0 :(得分:5)

while ((c=fgetc(img1)) != EOF)

这将从img1读取第一个字节。假设它不是EOF ...

fread(&buffer1, 1,1, img1);

这将从img1读取第二个字节。

fread(&buffer2, 1,1, img2);

这将从img2读取第一个字节。

if(buffer1 != buffer2)

现在我们将img2的第一个字节与img1的第二个字节进行比较。

如果它们恰好相同,我们将再次绕过循环,并且我们最终会将img2的第二个字节与img1的第四个字节进行比较。

看起来您可能认为fgetc已经过测试,看是否有另一个字节可用,然后fread会读取它。但不是。 fgetc从文件中读取一个字符,然后将其返回。如果你写

c = fgetc(fp);
它和你写的几乎完全一样

fread(&c, 1, 1, fp);

因此,对程序的最小修复就是摆脱

fread(&buffer1, 1,1, img1);

行,并将相等测试更改为

if(c != buffer2)

但这最终会让人感到困惑 - 后来的读者可能会怀疑,"为什么一个文件使用fgetc阅读,另一个使用fread?&# 34;

如果我写这篇文章,我可能会使用img1getc读取一个字节,使用img2getc读取一个字节,然后对它们进行比较。或者,我可以使用freadimg1中的N个字节读入字符数组,将img2中的N个字节读入第二个字符adday,并使用memcmp进行比较功能

另外,正如Paul Ogilvie在评论中提到的,由于这些是二进制文件,当您致电fopen打开它们时,您应指定"rb"模式。

答案 1 :(得分:1)

在我看来,你应该将它们转换成两个位图并进行标题和矩阵比较。你现在遇到麻烦,因为标题和标签可能不同。您可以找到许多有关此主题的教程,例如this one on Code Project

答案 2 :(得分:1)

正如其他评论中所述,fgetc正在读取流中的字符,因此在调用fread之前,2个流不同步。以下使用2次调用fgetc,然后使用返回值进行比较。

void compareFiles(char* path1, char* path2){
    FILE* img1; 
    FILE* img2; 

    if((img1 = fopen(path1,"rb")) == NULL || (img2 = fopen(path2,"rb")) == NULL){ 
        printf("ERROR fopen()\n"); 
        exit(-1); 
    }   

    int i=0;
    int byte1,byte2;

    while (((byte1=fgetc(img1)) != EOF) && ((byte2=fgetc(img2)) != EOF)){
        if(byte1 != byte2){
            printf("Byte differs\n IMG1: %c, IMG2: %c; Position %d\n",byte1,byte2,i);  
            i++; 
        } 
    }  

    fclose(img1);
    fclose(img2);
}