BMP图像差分/比较
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int main(int argc, char *argv[]) 6 { 7 int row, col; 8 int width, height, widthbyte, bitcount, imagesize, bytecount; 9 const char *magenta = NULL; 10 const char *magendiff = NULL; 11 unsigned char header[] = 12 { 13 0x42, 0x4D, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, // 2 AA->FileSize 14 0x00, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0x28, 0x00, // 10 BB->OffBits 15 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xDD, 0xDD, // 18 CC->Width 16 0xDD, 0xDD, 0x01, 0x00, 0xEE, 0xEE, 0x00, 0x00, // 22 DD->Height 17 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, // 28 EE->BitCount 18 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 34 FF->ImageSize 19 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 20 }; 21 22 FILE *fpA = NULL; 23 FILE *fpB = NULL; 24 FILE *fpC = NULL; 25 const char *filenameA = "A.bmp"; 26 const char *filenameB = "B.bmp"; 27 const char *filenameC = "C.bmp"; 28 unsigned char *rowbufA = NULL; 29 unsigned char *rowbufB = NULL; 30 31 const char * errmsg = NULL; 32 33 switch(argc) 34 { 35 case 1: 36 break; 37 case 2: 38 break; 39 case 3: 40 filenameA = argv[1]; 41 filenameB = argv[2]; 42 break; 43 case 4: 44 filenameA = argv[1]; 45 filenameB = argv[2]; 46 filenameC = argv[3]; 47 break; 48 } 49 50 do 51 { 52 fpA = fopen(filenameA, "rb"); 53 if(fpA == NULL) { errmsg = "A.bmp open failed"; break; }; 54 55 fpB = fopen(filenameB, "rb"); 56 if(fpB == NULL) { errmsg = "B.bmp open failed"; break; }; 57 58 // read file A.bmp 59 fread(header, sizeof(header), 1L, fpA); 60 width = *((int *)(header + 18)); 61 height = *((int *)(header + 22)); 62 bitcount = *((short *)(header + 28)); 63 imagesize = *((int *)(header + 34)); 64 widthbyte = (width * bitcount + 31) / 32 * 4; 65 bytecount = bitcount / 8; 66 switch(bitcount) 67 { 68 case 16: 69 magenta = "\x1F\x7C"; 70 magendiff = "\x1F\x7C"; 71 break; 72 case 24: 73 case 32: 74 magenta = "\x00\x00\x00\x00"; 75 magendiff = "\x00\x00\xFF\xFF"; 76 break; 77 default: 78 errmsg = "A.bitcount != 16 or 24 or 32"; 79 break; 80 } 81 if(errmsg) break; 82 83 // check file B.bmp 84 fread(header, sizeof(header), 1L, fpB); 85 if(width != *((int *)(header + 18))) { errmsg = "A.width != B.width"; break; } 86 if(height != *((int *)(header + 22))) { errmsg = "A.height != B.height"; break; } 87 if(bitcount != *((short *)(header + 28))) { errmsg = "A.bitcount != B.bitcount"; break; } 88 if(imagesize != *((int *)(header + 34))) { errmsg = "A.imagesize != B.imagesize"; break; } 89 90 rowbufA = (unsigned char *)malloc(widthbyte); 91 if(rowbufA == NULL) { errmsg = "rowbufA malloc failed"; break; } 92 93 rowbufB = (unsigned char *)malloc(widthbyte); 94 if(rowbufB == NULL) { errmsg = "rowbufB malloc failed"; break; } 95 96 fpC = fopen(filenameC, "wb"); 97 if(fpC == NULL) { errmsg = "C.bmp open failed"; break; }; 98 99 // wirte file C.bmp 100 fwrite(header, sizeof(header), 1L, fpC); 101 for(row = 0; row < height; row++) 102 { 103 fread(rowbufA, widthbyte, 1, fpA); 104 fread(rowbufB, widthbyte, 1, fpB); 105 106 for(col = 0; col < width; col++) 107 { 108 if(memcmp(rowbufA + bytecount * col, rowbufB + bytecount * col, bytecount) == 0) 109 { 110 memcpy(rowbufB + bytecount * col, magenta, bytecount); 111 } 112 else 113 { 114 memcpy(rowbufB + bytecount * col, magendiff, bytecount); 115 } 116 } 117 118 fwrite(rowbufB, widthbyte, 1, fpC); 119 } 120 121 } while(0); 122 123 if(fpA) fclose(fpA); 124 if(fpB) fclose(fpB); 125 if(fpC) fclose(fpC); 126 if(rowbufA) free(rowbufA); 127 if(rowbufB) free(rowbufB); 128 129 if(errmsg) 130 { 131 printf("%s\n", errmsg); 132 system("PAUSE"); 133 } 134 135 return 0; 136 }